(function(window, undefined) {
    var readyList, rootjQuery, core_strundefined = typeof undefined,
    location = window.location,
    document = window.document,
    docElem = document.documentElement,
    _jQuery = window.jQuery,
    _$ = window.$,
    class2type = {},
    core_deletedIds = [],
    core_version = "1.10.2",
    core_concat = core_deletedIds.concat,
    core_push = core_deletedIds.push,
    core_slice = core_deletedIds.slice,
    core_indexOf = core_deletedIds.indexOf,
    core_toString = class2type.toString,
    core_hasOwn = class2type.hasOwnProperty,
    core_trim = core_version.trim,
    jQuery = function(selector, context) {
        return new jQuery.fn.init(selector, context, rootjQuery)
    },
    core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
    core_rnotwhite = /\S+/g,
    rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
    rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
    rvalidchars = /^[\],:{}\s]*$/,
    rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
    rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
    rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
    rmsPrefix = /^-ms-/,
    rdashAlpha = /-([\da-z])/gi,
    fcamelCase = function(all, letter) {
        return letter.toUpperCase()
    },
    completed = function(event) {
        if (document.addEventListener || event.type === "load" || document.readyState === "complete") {
            detach();
            jQuery.ready()
        }
    },
    detach = function() {
        if (document.addEventListener) {
            document.removeEventListener("DOMContentLoaded", completed, false);
            window.removeEventListener("load", completed, false)
        } else {
            document.detachEvent("onreadystatechange", completed);
            window.detachEvent("onload", completed)
        }
    };
    jQuery.fn = jQuery.prototype = {
        jquery: core_version,
        constructor: jQuery,
        init: function(selector, context, rootjQuery) {
            var match, elem;
            if (!selector) {
                return this
            }
            if (typeof selector === "string") {
                if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) {
                    match = [null, selector, null]
                } else {
                    match = rquickExpr.exec(selector)
                }
                if (match && (match[1] || !context)) {
                    if (match[1]) {
                        context = context instanceof jQuery ? context[0] : context;
                        jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context: document, true));
                        if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
                            for (match in context) {
                                if (jQuery.isFunction(this[match])) {
                                    this[match](context[match])
                                } else {
                                    this.attr(match, context[match])
                                }
                            }
                        }
                        return this
                    } else {
                        elem = document.getElementById(match[2]);
                        if (elem && elem.parentNode) {
                            if (elem.id !== match[2]) {
                                return rootjQuery.find(selector)
                            }
                            this.length = 1;
                            this[0] = elem
                        }
                        this.context = document;
                        this.selector = selector;
                        return this
                    }
                } else if (!context || context.jquery) {
                    return (context || rootjQuery).find(selector)
                } else {
                    return this.constructor(context).find(selector)
                }
            } else if (selector.nodeType) {
                this.context = this[0] = selector;
                this.length = 1;
                return this
            } else if (jQuery.isFunction(selector)) {
                return rootjQuery.ready(selector)
            }
            if (selector.selector !== undefined) {
                this.selector = selector.selector;
                this.context = selector.context
            }
            return jQuery.makeArray(selector, this)
        },
        selector: "",
        length: 0,
        toArray: function() {
            return core_slice.call(this)
        },
        get: function(num) {
            return num == null ? this.toArray() : num < 0 ? this[this.length + num] : this[num]
        },
        pushStack: function(elems) {
            var ret = jQuery.merge(this.constructor(), elems);
            ret.prevObject = this;
            ret.context = this.context;
            return ret
        },
        each: function(callback, args) {
            return jQuery.each(this, callback, args)
        },
        ready: function(fn) {
            jQuery.ready.promise().done(fn);
            return this
        },
        slice: function() {
            return this.pushStack(core_slice.apply(this, arguments))
        },
        first: function() {
            return this.eq(0)
        },
        last: function() {
            return this.eq( - 1)
        },
        eq: function(i) {
            var len = this.length,
            j = +i + (i < 0 ? len: 0);
            return this.pushStack(j >= 0 && j < len ? [this[j]] : [])
        },
        map: function(callback) {
            return this.pushStack(jQuery.map(this,
            function(elem, i) {
                return callback.call(elem, i, elem)
            }))
        },
        end: function() {
            return this.prevObject || this.constructor(null)
        },
        push: core_push,
        sort: [].sort,
        splice: [].splice
    };
    jQuery.fn.init.prototype = jQuery.fn;
    jQuery.extend = jQuery.fn.extend = function() {
        var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;
        if (typeof target === "boolean") {
            deep = target;
            target = arguments[1] || {};
            i = 2
        }
        if (typeof target !== "object" && !jQuery.isFunction(target)) {
            target = {}
        }
        if (length === i) {
            target = this; --i
        }
        for (; i < length; i++) {
            if ((options = arguments[i]) != null) {
                for (name in options) {
                    src = target[name];
                    copy = options[name];
                    if (target === copy) {
                        continue
                    }
                    if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
                        if (copyIsArray) {
                            copyIsArray = false;
                            clone = src && jQuery.isArray(src) ? src: []
                        } else {
                            clone = src && jQuery.isPlainObject(src) ? src: {}
                        }
                        target[name] = jQuery.extend(deep, clone, copy)
                    } else if (copy !== undefined) {
                        target[name] = copy
                    }
                }
            }
        }
        return target
    };
    jQuery.extend({
        expando: "jQuery" + (core_version + Math.random()).replace(/\D/g, ""),
        noConflict: function(deep) {
            if (window.$ === jQuery) {
                window.$ = _$
            }
            if (deep && window.jQuery === jQuery) {
                window.jQuery = _jQuery
            }
            return jQuery
        },
        isReady: false,
        readyWait: 1,
        holdReady: function(hold) {
            if (hold) {
                jQuery.readyWait++
            } else {
                jQuery.ready(true)
            }
        },
        ready: function(wait) {
            if (wait === true ? --jQuery.readyWait: jQuery.isReady) {
                return
            }
            if (!document.body) {
                return setTimeout(jQuery.ready)
            }
            jQuery.isReady = true;
            if (wait !== true && --jQuery.readyWait > 0) {
                return
            }
            readyList.resolveWith(document, [jQuery]);
            if (jQuery.fn.trigger) {
                jQuery(document).trigger("ready").off("ready")
            }
        },
        isFunction: function(obj) {
            return jQuery.type(obj) === "function"
        },
        isArray: Array.isArray ||
        function(obj) {
            return jQuery.type(obj) === "array"
        },
        isWindow: function(obj) {
            return obj != null && obj == obj.window
        },
        isNumeric: function(obj) {
            return ! isNaN(parseFloat(obj)) && isFinite(obj)
        },
        type: function(obj) {
            if (obj == null) {
                return String(obj)
            }
            return typeof obj === "object" || typeof obj === "function" ? class2type[core_toString.call(obj)] || "object": typeof obj
        },
        isPlainObject: function(obj) {
            var key;
            if (!obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) {
                return false
            }
            try {
                if (obj.constructor && !core_hasOwn.call(obj, "constructor") && !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
                    return false
                }
            } catch(e) {
                return false
            }
            if (jQuery.support.ownLast) {
                for (key in obj) {
                    return core_hasOwn.call(obj, key)
                }
            }
            for (key in obj) {}
            return key === undefined || core_hasOwn.call(obj, key)
        },
        isEmptyObject: function(obj) {
            var name;
            for (name in obj) {
                return false
            }
            return true
        },
        error: function(msg) {
            throw new Error(msg)
        },
        parseHTML: function(data, context, keepScripts) {
            if (!data || typeof data !== "string") {
                return null
            }
            if (typeof context === "boolean") {
                keepScripts = context;
                context = false
            }
            context = context || document;
            var parsed = rsingleTag.exec(data),
            scripts = !keepScripts && [];
            if (parsed) {
                return [context.createElement(parsed[1])]
            }
            parsed = jQuery.buildFragment([data], context, scripts);
            if (scripts) {
                jQuery(scripts).remove()
            }
            return jQuery.merge([], parsed.childNodes)
        },
        parseJSON: function(data) {
            if (window.JSON && window.JSON.parse) {
                return window.JSON.parse(data)
            }
            if (data === null) {
                return data
            }
            if (typeof data === "string") {
                data = jQuery.trim(data);
                if (data) {
                    if (rvalidchars.test(data.replace(rvalidescape, "@").replace(rvalidtokens, "]").replace(rvalidbraces, ""))) {
                        return new Function("return " + data)()
                    }
                }
            }
            jQuery.error("Invalid JSON: " + data)
        },
        parseXML: function(data) {
            var xml, tmp;
            if (!data || typeof data !== "string") {
                return null
            }
            try {
                if (window.DOMParser) {
                    tmp = new DOMParser;
                    xml = tmp.parseFromString(data, "text/xml")
                } else {
                    xml = new ActiveXObject("Microsoft.XMLDOM");
                    xml.async = "false";
                    xml.loadXML(data)
                }
            } catch(e) {
                xml = undefined
            }
            if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) {
                jQuery.error("Invalid XML: " + data)
            }
            return xml
        },
        noop: function() {},
        globalEval: function(data) {
            if (data && jQuery.trim(data)) { (window.execScript ||
                function(data) {
                    window["eval"].call(window, data)
                })(data)
            }
        },
        camelCase: function(string) {
            return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase)
        },
        nodeName: function(elem, name) {
            return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase()
        },
        each: function(obj, callback, args) {
            var value, i = 0,
            length = obj.length,
            isArray = isArraylike(obj);
            if (args) {
                if (isArray) {
                    for (; i < length; i++) {
                        value = callback.apply(obj[i], args);
                        if (value === false) {
                            break
                        }
                    }
                } else {
                    for (i in obj) {
                        value = callback.apply(obj[i], args);
                        if (value === false) {
                            break
                        }
                    }
                }
            } else {
                if (isArray) {
                    for (; i < length; i++) {
                        value = callback.call(obj[i], i, obj[i]);
                        if (value === false) {
                            break
                        }
                    }
                } else {
                    for (i in obj) {
                        value = callback.call(obj[i], i, obj[i]);
                        if (value === false) {
                            break
                        }
                    }
                }
            }
            return obj
        },
        trim: core_trim && !core_trim.call("﻿ ") ?
        function(text) {
            return text == null ? "": core_trim.call(text)
        }: function(text) {
            return text == null ? "": (text + "").replace(rtrim, "")
        },
        makeArray: function(arr, results) {
            var ret = results || [];
            if (arr != null) {
                if (isArraylike(Object(arr))) {
                    jQuery.merge(ret, typeof arr === "string" ? [arr] : arr)
                } else {
                    core_push.call(ret, arr)
                }
            }
            return ret
        },
        inArray: function(elem, arr, i) {
            var len;
            if (arr) {
                if (core_indexOf) {
                    return core_indexOf.call(arr, elem, i)
                }
                len = arr.length;
                i = i ? i < 0 ? Math.max(0, len + i) : i: 0;
                for (; i < len; i++) {
                    if (i in arr && arr[i] === elem) {
                        return i
                    }
                }
            }
            return - 1
        },
        merge: function(first, second) {
            var l = second.length,
            i = first.length,
            j = 0;
            if (typeof l === "number") {
                for (; j < l; j++) {
                    first[i++] = second[j]
                }
            } else {
                while (second[j] !== undefined) {
                    first[i++] = second[j++]
                }
            }
            first.length = i;
            return first
        },
        grep: function(elems, callback, inv) {
            var retVal, ret = [],
            i = 0,
            length = elems.length;
            inv = !!inv;
            for (; i < length; i++) {
                retVal = !!callback(elems[i], i);
                if (inv !== retVal) {
                    ret.push(elems[i])
                }
            }
            return ret
        },
        map: function(elems, callback, arg) {
            var value, i = 0,
            length = elems.length,
            isArray = isArraylike(elems),
            ret = [];
            if (isArray) {
                for (; i < length; i++) {
                    value = callback(elems[i], i, arg);
                    if (value != null) {
                        ret[ret.length] = value
                    }
                }
            } else {
                for (i in elems) {
                    value = callback(elems[i], i, arg);
                    if (value != null) {
                        ret[ret.length] = value
                    }
                }
            }
            return core_concat.apply([], ret)
        },
        guid: 1,
        proxy: function(fn, context) {
            var args, proxy, tmp;
            if (typeof context === "string") {
                tmp = fn[context];
                context = fn;
                fn = tmp
            }
            if (!jQuery.isFunction(fn)) {
                return undefined
            }
            args = core_slice.call(arguments, 2);
            proxy = function() {
                return fn.apply(context || this, args.concat(core_slice.call(arguments)))
            };
            proxy.guid = fn.guid = fn.guid || jQuery.guid++;
            return proxy
        },
        access: function(elems, fn, key, value, chainable, emptyGet, raw) {
            var i = 0,
            length = elems.length,
            bulk = key == null;
            if (jQuery.type(key) === "object") {
                chainable = true;
                for (i in key) {
                    jQuery.access(elems, fn, i, key[i], true, emptyGet, raw)
                }
            } else if (value !== undefined) {
                chainable = true;
                if (!jQuery.isFunction(value)) {
                    raw = true
                }
                if (bulk) {
                    if (raw) {
                        fn.call(elems, value);
                        fn = null
                    } else {
                        bulk = fn;
                        fn = function(elem, key, value) {
                            return bulk.call(jQuery(elem), value)
                        }
                    }
                }
                if (fn) {
                    for (; i < length; i++) {
                        fn(elems[i], key, raw ? value: value.call(elems[i], i, fn(elems[i], key)))
                    }
                }
            }
            return chainable ? elems: bulk ? fn.call(elems) : length ? fn(elems[0], key) : emptyGet
        },
        now: function() {
            return (new Date).getTime()
        },
        swap: function(elem, options, callback, args) {
            var ret, name, old = {};
            for (name in options) {
                old[name] = elem.style[name];
                elem.style[name] = options[name]
            }
            ret = callback.apply(elem, args || []);
            for (name in options) {
                elem.style[name] = old[name]
            }
            return ret
        }
    });
    jQuery.ready.promise = function(obj) {
        if (!readyList) {
            readyList = jQuery.Deferred();
            if (document.readyState === "complete") {
                setTimeout(jQuery.ready)
            } else if (document.addEventListener) {
                document.addEventListener("DOMContentLoaded", completed, false);
                window.addEventListener("load", completed, false)
            } else {
                document.attachEvent("onreadystatechange", completed);
                window.attachEvent("onload", completed);
                var top = false;
                try {
                    top = window.frameElement == null && document.documentElement
                } catch(e) {}
                if (top && top.doScroll) { (function doScrollCheck() {
                        if (!jQuery.isReady) {
                            try {
                                top.doScroll("left")
                            } catch(e) {
                                return setTimeout(doScrollCheck, 50)
                            }
                            detach();
                            jQuery.ready()
                        }
                    })()
                }
            }
        }
        return readyList.promise(obj)
    };
    jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),
    function(i, name) {
        class2type["[object " + name + "]"] = name.toLowerCase()
    });
    function isArraylike(obj) {
        var length = obj.length,
        type = jQuery.type(obj);
        if (jQuery.isWindow(obj)) {
            return false
        }
        if (obj.nodeType === 1 && length) {
            return true
        }
        return type === "array" || type !== "function" && (length === 0 || typeof length === "number" && length > 0 && length - 1 in obj)
    }
    rootjQuery = jQuery(document); (function(window, undefined) {
        var i, support, cachedruns, Expr, getText, isXML, compile, outermostContext, sortInput, setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, expando = "sizzle" + -new Date,
        preferredDoc = window.document,
        dirruns = 0,
        done = 0,
        classCache = createCache(),
        tokenCache = createCache(),
        compilerCache = createCache(),
        hasDuplicate = false,
        sortOrder = function(a, b) {
            if (a === b) {
                hasDuplicate = true;
                return 0
            }
            return 0
        },
        strundefined = typeof undefined,
        MAX_NEGATIVE = 1 << 31,
        hasOwn = {}.hasOwnProperty,
        arr = [],
        pop = arr.pop,
        push_native = arr.push,
        push = arr.push,
        slice = arr.slice,
        indexOf = arr.indexOf ||
        function(elem) {
            var i = 0,
            len = this.length;
            for (; i < len; i++) {
                if (this[i] === elem) {
                    return i
                }
            }
            return - 1
        },
        booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
        whitespace = "[\\x20\\t\\r\\n\\f]",
        characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
        identifier = characterEncoding.replace("w", "w#"),
        attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
        pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace(3, 8) + ")*)|.*)\\)|)",
        rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
        rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
        rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
        rsibling = new RegExp(whitespace + "*[+~]"),
        rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g"),
        rpseudo = new RegExp(pseudos),
        ridentifier = new RegExp("^" + identifier + "$"),
        matchExpr = {
            ID: new RegExp("^#(" + characterEncoding + ")"),
            CLASS: new RegExp("^\\.(" + characterEncoding + ")"),
            TAG: new RegExp("^(" + characterEncoding.replace("w", "w*") + ")"),
            ATTR: new RegExp("^" + attributes),
            PSEUDO: new RegExp("^" + pseudos),
            CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
            bool: new RegExp("^(?:" + booleans + ")$", "i"),
            needsContext: new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
        },
        rnative = /^[^{]+\{\s*\[native \w/,
        rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
        rinputs = /^(?:input|select|textarea|button)$/i,
        rheader = /^h\d$/i,
        rescape = /'|\\/g,
        runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
        funescape = function(_, escaped, escapedWhitespace) {
            var high = "0x" + escaped - 65536;
            return high !== high || escapedWhitespace ? escaped: high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320)
        };
        try {
            push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);
            arr[preferredDoc.childNodes.length].nodeType
        } catch(e) {
            push = {
                apply: arr.length ?
                function(target, els) {
                    push_native.apply(target, slice.call(els))
                }: function(target, els) {
                    var j = target.length,
                    i = 0;
                    while (target[j++] = els[i++]) {}
                    target.length = j - 1
                }
            }
        }
        function Sizzle(selector, context, results, seed) {
            var match, elem, m, nodeType, i, groups, old, nid, newContext, newSelector;
            if ((context ? context.ownerDocument || context: preferredDoc) !== document) {
                setDocument(context)
            }
            context = context || document;
            results = results || [];
            if (!selector || typeof selector !== "string") {
                return results
            }
            if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
                return []
            }
            if (documentIsHTML && !seed) {
                if (match = rquickExpr.exec(selector)) {
                    if (m = match[1]) {
                        if (nodeType === 9) {
                            elem = context.getElementById(m);
                            if (elem && elem.parentNode) {
                                if (elem.id === m) {
                                    results.push(elem);
                                    return results
                                }
                            } else {
                                return results
                            }
                        } else {
                            if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains(context, elem) && elem.id === m) {
                                results.push(elem);
                                return results
                            }
                        }
                    } else if (match[2]) {
                        push.apply(results, context.getElementsByTagName(selector));
                        return results
                    } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {
                        push.apply(results, context.getElementsByClassName(m));
                        return results
                    }
                }
                if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
                    nid = old = expando;
                    newContext = context;
                    newSelector = nodeType === 9 && selector;
                    if (nodeType === 1 && context.nodeName.toLowerCase() !== "object") {
                        groups = tokenize(selector);
                        if (old = context.getAttribute("id")) {
                            nid = old.replace(rescape, "\\$&")
                        } else {
                            context.setAttribute("id", nid)
                        }
                        nid = "[id='" + nid + "'] ";
                        i = groups.length;
                        while (i--) {
                            groups[i] = nid + toSelector(groups[i])
                        }
                        newContext = rsibling.test(selector) && context.parentNode || context;
                        newSelector = groups.join(",")
                    }
                    if (newSelector) {
                        try {
                            push.apply(results, newContext.querySelectorAll(newSelector));
                            return results
                        } catch(qsaError) {} finally {
                            if (!old) {
                                context.removeAttribute("id")
                            }
                        }
                    }
                }
            }
            return select(selector.replace(rtrim, "$1"), context, results, seed)
        }
        function createCache() {
            var keys = [];
            function cache(key, value) {
                if (keys.push(key += " ") > Expr.cacheLength) {
                    delete cache[keys.shift()]
                }
                return cache[key] = value
            }
            return cache
        }
        function markFunction(fn) {
            fn[expando] = true;
            return fn
        }
        function assert(fn) {
            var div = document.createElement("div");
            try {
                return !! fn(div)
            } catch(e) {
                return false
            } finally {
                if (div.parentNode) {
                    div.parentNode.removeChild(div)
                }
                div = null
            }
        }
        function addHandle(attrs, handler) {
            var arr = attrs.split("|"),
            i = attrs.length;
            while (i--) {
                Expr.attrHandle[arr[i]] = handler
            }
        }
        function siblingCheck(a, b) {
            var cur = b && a,
            diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
            if (diff) {
                return diff
            }
            if (cur) {
                while (cur = cur.nextSibling) {
                    if (cur === b) {
                        return - 1
                    }
                }
            }
            return a ? 1 : -1
        }
        function createInputPseudo(type) {
            return function(elem) {
                var name = elem.nodeName.toLowerCase();
                return name === "input" && elem.type === type
            }
        }
        function createButtonPseudo(type) {
            return function(elem) {
                var name = elem.nodeName.toLowerCase();
                return (name === "input" || name === "button") && elem.type === type
            }
        }
        function createPositionalPseudo(fn) {
            return markFunction(function(argument) {
                argument = +argument;
                return markFunction(function(seed, matches) {
                    var j, matchIndexes = fn([], seed.length, argument),
                    i = matchIndexes.length;
                    while (i--) {
                        if (seed[j = matchIndexes[i]]) {
                            seed[j] = !(matches[j] = seed[j])
                        }
                    }
                })
            })
        }
        isXML = Sizzle.isXML = function(elem) {
            var documentElement = elem && (elem.ownerDocument || elem).documentElement;
            return documentElement ? documentElement.nodeName !== "HTML": false
        };
        support = Sizzle.support = {};
        setDocument = Sizzle.setDocument = function(node) {
            var doc = node ? node.ownerDocument || node: preferredDoc,
            parent = doc.defaultView;
            if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
                return document
            }
            document = doc;
            docElem = doc.documentElement;
            documentIsHTML = !isXML(doc);
            if (parent && parent.attachEvent && parent !== parent.top) {
                parent.attachEvent("onbeforeunload",
                function() {
                    setDocument()
                })
            }
            support.attributes = assert(function(div) {
                div.className = "i";
                return ! div.getAttribute("className")
            });
            support.getElementsByTagName = assert(function(div) {
                div.appendChild(doc.createComment(""));
                return ! div.getElementsByTagName("*").length
            });
            support.getElementsByClassName = assert(function(div) {
                div.innerHTML = "<div class='a'></div><div class='a i'></div>";
                div.firstChild.className = "i";
                return div.getElementsByClassName("i").length === 2
            });
            support.getById = assert(function(div) {
                docElem.appendChild(div).id = expando;
                return ! doc.getElementsByName || !doc.getElementsByName(expando).length
            });
            if (support.getById) {
                Expr.find["ID"] = function(id, context) {
                    if (typeof context.getElementById !== strundefined && documentIsHTML) {
                        var m = context.getElementById(id);
                        return m && m.parentNode ? [m] : []
                    }
                };
                Expr.filter["ID"] = function(id) {
                    var attrId = id.replace(runescape, funescape);
                    return function(elem) {
                        return elem.getAttribute("id") === attrId
                    }
                }
            } else {
                delete Expr.find["ID"];
                Expr.filter["ID"] = function(id) {
                    var attrId = id.replace(runescape, funescape);
                    return function(elem) {
                        var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
                        return node && node.value === attrId
                    }
                }
            }
            Expr.find["TAG"] = support.getElementsByTagName ?
            function(tag, context) {
                if (typeof context.getElementsByTagName !== strundefined) {
                    return context.getElementsByTagName(tag)
                }
            }: function(tag, context) {
                var elem, tmp = [],
                i = 0,
                results = context.getElementsByTagName(tag);
                if (tag === "*") {
                    while (elem = results[i++]) {
                        if (elem.nodeType === 1) {
                            tmp.push(elem)
                        }
                    }
                    return tmp
                }
                return results
            };
            Expr.find["CLASS"] = support.getElementsByClassName &&
            function(className, context) {
                if (typeof context.getElementsByClassName !== strundefined && documentIsHTML) {
                    return context.getElementsByClassName(className)
                }
            };
            rbuggyMatches = [];
            rbuggyQSA = [];
            if (support.qsa = rnative.test(doc.querySelectorAll)) {
                assert(function(div) {
                    div.innerHTML = "<select><option selected=''></option></select>";
                    if (!div.querySelectorAll("[selected]").length) {
                        rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")")
                    }
                    if (!div.querySelectorAll(":checked").length) {
                        rbuggyQSA.push(":checked")
                    }
                });
                assert(function(div) {
                    var input = doc.createElement("input");
                    input.setAttribute("type", "hidden");
                    div.appendChild(input).setAttribute("t", "");
                    if (div.querySelectorAll("[t^='']").length) {
                        rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")")
                    }
                    if (!div.querySelectorAll(":enabled").length) {
                        rbuggyQSA.push(":enabled", ":disabled")
                    }
                    div.querySelectorAll("*,:x");
                    rbuggyQSA.push(",.*:")
                })
            }
            if (support.matchesSelector = rnative.test(matches = docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {
                assert(function(div) {
                    support.disconnectedMatch = matches.call(div, "div");
                    matches.call(div, "[s!='']:x");
                    rbuggyMatches.push("!=", pseudos)
                })
            }
            rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
            rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
            contains = rnative.test(docElem.contains) || docElem.compareDocumentPosition ?
            function(a, b) {
                var adown = a.nodeType === 9 ? a.documentElement: a,
                bup = b && b.parentNode;
                return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16))
            }: function(a, b) {
                if (b) {
                    while (b = b.parentNode) {
                        if (b === a) {
                            return true
                        }
                    }
                }
                return false
            };
            sortOrder = docElem.compareDocumentPosition ?
            function(a, b) {
                if (a === b) {
                    hasDuplicate = true;
                    return 0
                }
                var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition(b);
                if (compare) {
                    if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
                        if (a === doc || contains(preferredDoc, a)) {
                            return - 1
                        }
                        if (b === doc || contains(preferredDoc, b)) {
                            return 1
                        }
                        return sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0
                    }
                    return compare & 4 ? -1 : 1
                }
                return a.compareDocumentPosition ? -1 : 1
            }: function(a, b) {
                var cur, i = 0,
                aup = a.parentNode,
                bup = b.parentNode,
                ap = [a],
                bp = [b];
                if (a === b) {
                    hasDuplicate = true;
                    return 0
                } else if (!aup || !bup) {
                    return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0
                } else if (aup === bup) {
                    return siblingCheck(a, b)
                }
                cur = a;
                while (cur = cur.parentNode) {
                    ap.unshift(cur)
                }
                cur = b;
                while (cur = cur.parentNode) {
                    bp.unshift(cur)
                }
                while (ap[i] === bp[i]) {
                    i++
                }
                return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0
            };
            return doc
        };
        Sizzle.matches = function(expr, elements) {
            return Sizzle(expr, null, null, elements)
        };
        Sizzle.matchesSelector = function(elem, expr) {
            if ((elem.ownerDocument || elem) !== document) {
                setDocument(elem)
            }
            expr = expr.replace(rattributeQuotes, "='$1']");
            if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
                try {
                    var ret = matches.call(elem, expr);
                    if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) {
                        return ret
                    }
                } catch(e) {}
            }
            return Sizzle(expr, document, null, [elem]).length > 0
        };
        Sizzle.contains = function(context, elem) {
            if ((context.ownerDocument || context) !== document) {
                setDocument(context)
            }
            return contains(context, elem)
        };
        Sizzle.attr = function(elem, name) {
            if ((elem.ownerDocument || elem) !== document) {
                setDocument(elem)
            }
            var fn = Expr.attrHandle[name.toLowerCase()],
            val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
            return val === undefined ? support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value: null: val
        };
        Sizzle.error = function(msg) {
            throw new Error("Syntax error, unrecognized expression: " + msg)
        };
        Sizzle.uniqueSort = function(results) {
            var elem, duplicates = [],
            j = 0,
            i = 0;
            hasDuplicate = !support.detectDuplicates;
            sortInput = !support.sortStable && results.slice(0);
            results.sort(sortOrder);
            if (hasDuplicate) {
                while (elem = results[i++]) {
                    if (elem === results[i]) {
                        j = duplicates.push(i)
                    }
                }
                while (j--) {
                    results.splice(duplicates[j], 1)
                }
            }
            return results
        };
        getText = Sizzle.getText = function(elem) {
            var node, ret = "",
            i = 0,
            nodeType = elem.nodeType;
            if (!nodeType) {
                for (; node = elem[i]; i++) {
                    ret += getText(node)
                }
            } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
                if (typeof elem.textContent === "string") {
                    return elem.textContent
                } else {
                    for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
                        ret += getText(elem)
                    }
                }
            } else if (nodeType === 3 || nodeType === 4) {
                return elem.nodeValue
            }
            return ret
        };
        Expr = Sizzle.selectors = {
            cacheLength: 50,
            createPseudo: markFunction,
            match: matchExpr,
            attrHandle: {},
            find: {},
            relative: {
                ">": {
                    dir: "parentNode",
                    first: true
                },
                " ": {
                    dir: "parentNode"
                },
                "+": {
                    dir: "previousSibling",
                    first: true
                },
                "~": {
                    dir: "previousSibling"
                }
            },
            preFilter: {
                ATTR: function(match) {
                    match[1] = match[1].replace(runescape, funescape);
                    match[3] = (match[4] || match[5] || "").replace(runescape, funescape);
                    if (match[2] === "~=") {
                        match[3] = " " + match[3] + " "
                    }
                    return match.slice(0, 4)
                },
                CHILD: function(match) {
                    match[1] = match[1].toLowerCase();
                    if (match[1].slice(0, 3) === "nth") {
                        if (!match[3]) {
                            Sizzle.error(match[0])
                        }
                        match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
                        match[5] = +(match[7] + match[8] || match[3] === "odd")
                    } else if (match[3]) {
                        Sizzle.error(match[0])
                    }
                    return match
                },
                PSEUDO: function(match) {
                    var excess, unquoted = !match[5] && match[2];
                    if (matchExpr["CHILD"].test(match[0])) {
                        return null
                    }
                    if (match[3] && match[4] !== undefined) {
                        match[2] = match[4]
                    } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
                        match[0] = match[0].slice(0, excess);
                        match[2] = unquoted.slice(0, excess)
                    }
                    return match.slice(0, 3)
                }
            },
            filter: {
                TAG: function(nodeNameSelector) {
                    var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
                    return nodeNameSelector === "*" ?
                    function() {
                        return true
                    }: function(elem) {
                        return elem.nodeName && elem.nodeName.toLowerCase() === nodeName
                    }
                },
                CLASS: function(className) {
                    var pattern = classCache[className + " "];
                    return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className,
                    function(elem) {
                        return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "")
                    })
                },
                ATTR: function(name, operator, check) {
                    return function(elem) {
                        var result = Sizzle.attr(elem, name);
                        if (result == null) {
                            return operator === "!="
                        }
                        if (!operator) {
                            return true
                        }
                        result += "";
                        return operator === "=" ? result === check: operator === "!=" ? result !== check: operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice( - check.length) === check: operator === "~=" ? (" " + result + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-": false
                    }
                },
                CHILD: function(type, what, argument, first, last) {
                    var simple = type.slice(0, 3) !== "nth",
                    forward = type.slice( - 4) !== "last",
                    ofType = what === "of-type";
                    return first === 1 && last === 0 ?
                    function(elem) {
                        return !! elem.parentNode
                    }: function(elem, context, xml) {
                        var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? "nextSibling": "previousSibling",
                        parent = elem.parentNode,
                        name = ofType && elem.nodeName.toLowerCase(),
                        useCache = !xml && !ofType;
                        if (parent) {
                            if (simple) {
                                while (dir) {
                                    node = elem;
                                    while (node = node[dir]) {
                                        if (ofType ? node.nodeName.toLowerCase() === name: node.nodeType === 1) {
                                            return false
                                        }
                                    }
                                    start = dir = type === "only" && !start && "nextSibling"
                                }
                                return true
                            }
                            start = [forward ? parent.firstChild: parent.lastChild];
                            if (forward && useCache) {
                                outerCache = parent[expando] || (parent[expando] = {});
                                cache = outerCache[type] || [];
                                nodeIndex = cache[0] === dirruns && cache[1];
                                diff = cache[0] === dirruns && cache[2];
                                node = nodeIndex && parent.childNodes[nodeIndex];
                                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
                                    if (node.nodeType === 1 && ++diff && node === elem) {
                                        outerCache[type] = [dirruns, nodeIndex, diff];
                                        break
                                    }
                                }
                            } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
                                diff = cache[1]
                            } else {
                                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
                                    if ((ofType ? node.nodeName.toLowerCase() === name: node.nodeType === 1) && ++diff) {
                                        if (useCache) { (node[expando] || (node[expando] = {}))[type] = [dirruns, diff]
                                        }
                                        if (node === elem) {
                                            break
                                        }
                                    }
                                }
                            }
                            diff -= last;
                            return diff === first || diff % first === 0 && diff / first >= 0
                        }
                    }
                },
                PSEUDO: function(pseudo, argument) {
                    var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo);
                    if (fn[expando]) {
                        return fn(argument)
                    }
                    if (fn.length > 1) {
                        args = [pseudo, pseudo, "", argument];
                        return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function(seed, matches) {
                            var idx, matched = fn(seed, argument),
                            i = matched.length;
                            while (i--) {
                                idx = indexOf.call(seed, matched[i]);
                                seed[idx] = !(matches[idx] = matched[i])
                            }
                        }) : function(elem) {
                            return fn(elem, 0, args)
                        }
                    }
                    return fn
                }
            },
            pseudos: {
                not: markFunction(function(selector) {
                    var input = [],
                    results = [],
                    matcher = compile(selector.replace(rtrim, "$1"));
                    return matcher[expando] ? markFunction(function(seed, matches, context, xml) {
                        var elem, unmatched = matcher(seed, null, xml, []),
                        i = seed.length;
                        while (i--) {
                            if (elem = unmatched[i]) {
                                seed[i] = !(matches[i] = elem)
                            }
                        }
                    }) : function(elem, context, xml) {
                        input[0] = elem;
                        matcher(input, null, xml, results);
                        return ! results.pop()
                    }
                }),
                has: markFunction(function(selector) {
                    return function(elem) {
                        return Sizzle(selector, elem).length > 0
                    }
                }),
                contains: markFunction(function(text) {
                    return function(elem) {
                        return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1
                    }
                }),
                lang: markFunction(function(lang) {
                    if (!ridentifier.test(lang || "")) {
                        Sizzle.error("unsupported lang: " + lang)
                    }
                    lang = lang.replace(runescape, funescape).toLowerCase();
                    return function(elem) {
                        var elemLang;
                        do {
                            if (elemLang = documentIsHTML ? elem.lang: elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
                                elemLang = elemLang.toLowerCase();
                                return elemLang === lang || elemLang.indexOf(lang + "-") === 0
                            }
                        } while (( elem = elem . parentNode ) && elem.nodeType === 1);
                        return false
                    }
                }),
                target: function(elem) {
                    var hash = window.location && window.location.hash;
                    return hash && hash.slice(1) === elem.id
                },
                root: function(elem) {
                    return elem === docElem
                },
                focus: function(elem) {
                    return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex)
                },
                enabled: function(elem) {
                    return elem.disabled === false
                },
                disabled: function(elem) {
                    return elem.disabled === true
                },
                checked: function(elem) {
                    var nodeName = elem.nodeName.toLowerCase();
                    return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected
                },
                selected: function(elem) {
                    if (elem.parentNode) {
                        elem.parentNode.selectedIndex
                    }
                    return elem.selected === true
                },
                empty: function(elem) {
                    for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
                        if (elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4) {
                            return false
                        }
                    }
                    return true
                },
                parent: function(elem) {
                    return ! Expr.pseudos["empty"](elem)
                },
                header: function(elem) {
                    return rheader.test(elem.nodeName)
                },
                input: function(elem) {
                    return rinputs.test(elem.nodeName)
                },
                button: function(elem) {
                    var name = elem.nodeName.toLowerCase();
                    return name === "input" && elem.type === "button" || name === "button"
                },
                text: function(elem) {
                    var attr;
                    return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ((attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type)
                },
                first: createPositionalPseudo(function() {
                    return [0]
                }),
                last: createPositionalPseudo(function(matchIndexes, length) {
                    return [length - 1]
                }),
                eq: createPositionalPseudo(function(matchIndexes, length, argument) {
                    return [argument < 0 ? argument + length: argument]
                }),
                even: createPositionalPseudo(function(matchIndexes, length) {
                    var i = 0;
                    for (; i < length; i += 2) {
                        matchIndexes.push(i)
                    }
                    return matchIndexes
                }),
                odd: createPositionalPseudo(function(matchIndexes, length) {
                    var i = 1;
                    for (; i < length; i += 2) {
                        matchIndexes.push(i)
                    }
                    return matchIndexes
                }),
                lt: createPositionalPseudo(function(matchIndexes, length, argument) {
                    var i = argument < 0 ? argument + length: argument;
                    for (; --i >= 0;) {
                        matchIndexes.push(i)
                    }
                    return matchIndexes
                }),
                gt: createPositionalPseudo(function(matchIndexes, length, argument) {
                    var i = argument < 0 ? argument + length: argument;
                    for (; ++i < length;) {
                        matchIndexes.push(i)
                    }
                    return matchIndexes
                })
            }
        };
        Expr.pseudos["nth"] = Expr.pseudos["eq"];
        for (i in {
            radio: true,
            checkbox: true,
            file: true,
            password: true,
            image: true
        }) {
            Expr.pseudos[i] = createInputPseudo(i)
        }
        for (i in {
            submit: true,
            reset: true
        }) {
            Expr.pseudos[i] = createButtonPseudo(i)
        }
        function setFilters() {}
        setFilters.prototype = Expr.filters = Expr.pseudos;
        Expr.setFilters = new setFilters;
        function tokenize(selector, parseOnly) {
            var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + " "];
            if (cached) {
                return parseOnly ? 0 : cached.slice(0)
            }
            soFar = selector;
            groups = [];
            preFilters = Expr.preFilter;
            while (soFar) {
                if (!matched || (match = rcomma.exec(soFar))) {
                    if (match) {
                        soFar = soFar.slice(match[0].length) || soFar
                    }
                    groups.push(tokens = [])
                }
                matched = false;
                if (match = rcombinators.exec(soFar)) {
                    matched = match.shift();
                    tokens.push({
                        value: matched,
                        type: match[0].replace(rtrim, " ")
                    });
                    soFar = soFar.slice(matched.length)
                }
                for (type in Expr.filter) {
                    if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
                        matched = match.shift();
                        tokens.push({
                            value: matched,
                            type: type,
                            matches: match
                        });
                        soFar = soFar.slice(matched.length)
                    }
                }
                if (!matched) {
                    break
                }
            }
            return parseOnly ? soFar.length: soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0)
        }
        function toSelector(tokens) {
            var i = 0,
            len = tokens.length,
            selector = "";
            for (; i < len; i++) {
                selector += tokens[i].value
            }
            return selector
        }
        function addCombinator(matcher, combinator, base) {
            var dir = combinator.dir,
            checkNonElements = base && dir === "parentNode",
            doneName = done++;
            return combinator.first ?
            function(elem, context, xml) {
                while (elem = elem[dir]) {
                    if (elem.nodeType === 1 || checkNonElements) {
                        return matcher(elem, context, xml)
                    }
                }
            }: function(elem, context, xml) {
                var data, cache, outerCache, dirkey = dirruns + " " + doneName;
                if (xml) {
                    while (elem = elem[dir]) {
                        if (elem.nodeType === 1 || checkNonElements) {
                            if (matcher(elem, context, xml)) {
                                return true
                            }
                        }
                    }
                } else {
                    while (elem = elem[dir]) {
                        if (elem.nodeType === 1 || checkNonElements) {
                            outerCache = elem[expando] || (elem[expando] = {});
                            if ((cache = outerCache[dir]) && cache[0] === dirkey) {
                                if ((data = cache[1]) === true || data === cachedruns) {
                                    return data === true
                                }
                            } else {
                                cache = outerCache[dir] = [dirkey];
                                cache[1] = matcher(elem, context, xml) || cachedruns;
                                if (cache[1] === true) {
                                    return true
                                }
                            }
                        }
                    }
                }
            }
        }
        function elementMatcher(matchers) {
            return matchers.length > 1 ?
            function(elem, context, xml) {
                var i = matchers.length;
                while (i--) {
                    if (!matchers[i](elem, context, xml)) {
                        return false
                    }
                }
                return true
            }: matchers[0]
        }
        function condense(unmatched, map, filter, context, xml) {
            var elem, newUnmatched = [],
            i = 0,
            len = unmatched.length,
            mapped = map != null;
            for (; i < len; i++) {
                if (elem = unmatched[i]) {
                    if (!filter || filter(elem, context, xml)) {
                        newUnmatched.push(elem);
                        if (mapped) {
                            map.push(i)
                        }
                    }
                }
            }
            return newUnmatched
        }
        function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
            if (postFilter && !postFilter[expando]) {
                postFilter = setMatcher(postFilter)
            }
            if (postFinder && !postFinder[expando]) {
                postFinder = setMatcher(postFinder, postSelector)
            }
            return markFunction(function(seed, results, context, xml) {
                var temp, i, elem, preMap = [],
                postMap = [],
                preexisting = results.length,
                elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
                matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,
                matcherOut = matcher ? postFinder || (seed ? preFilter: preexisting || postFilter) ? [] : results: matcherIn;
                if (matcher) {
                    matcher(matcherIn, matcherOut, context, xml)
                }
                if (postFilter) {
                    temp = condense(matcherOut, postMap);
                    postFilter(temp, [], context, xml);
                    i = temp.length;
                    while (i--) {
                        if (elem = temp[i]) {
                            matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem)
                        }
                    }
                }
                if (seed) {
                    if (postFinder || preFilter) {
                        if (postFinder) {
                            temp = [];
                            i = matcherOut.length;
                            while (i--) {
                                if (elem = matcherOut[i]) {
                                    temp.push(matcherIn[i] = elem)
                                }
                            }
                            postFinder(null, matcherOut = [], temp, xml)
                        }
                        i = matcherOut.length;
                        while (i--) {
                            if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf.call(seed, elem) : preMap[i]) > -1) {
                                seed[temp] = !(results[temp] = elem)
                            }
                        }
                    }
                } else {
                    matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
                    if (postFinder) {
                        postFinder(null, results, matcherOut, xml)
                    } else {
                        push.apply(results, matcherOut)
                    }
                }
            })
        }
        function matcherFromTokens(tokens) {
            var checkContext, matcher, j, len = tokens.length,
            leadingRelative = Expr.relative[tokens[0].type],
            implicitRelative = leadingRelative || Expr.relative[" "],
            i = leadingRelative ? 1 : 0,
            matchContext = addCombinator(function(elem) {
                return elem === checkContext
            },
            implicitRelative, true),
            matchAnyContext = addCombinator(function(elem) {
                return indexOf.call(checkContext, elem) > -1
            },
            implicitRelative, true),
            matchers = [function(elem, context, xml) {
                return ! leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml))
            }];
            for (; i < len; i++) {
                if (matcher = Expr.relative[tokens[i].type]) {
                    matchers = [addCombinator(elementMatcher(matchers), matcher)]
                } else {
                    matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
                    if (matcher[expando]) {
                        j = ++i;
                        for (; j < len; j++) {
                            if (Expr.relative[tokens[j].type]) {
                                break
                            }
                        }
                        return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({
                            value: tokens[i - 2].type === " " ? "*": ""
                        })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens))
                    }
                    matchers.push(matcher)
                }
            }
            return elementMatcher(matchers)
        }
        function matcherFromGroupMatchers(elementMatchers, setMatchers) {
            var matcherCachedRuns = 0,
            bySet = setMatchers.length > 0,
            byElement = elementMatchers.length > 0,
            superMatcher = function(seed, context, xml, results, expandContext) {
                var elem, j, matcher, setMatched = [],
                matchedCount = 0,
                i = "0",
                unmatched = seed && [],
                outermost = expandContext != null,
                contextBackup = outermostContext,
                elems = seed || byElement && Expr.find["TAG"]("*", expandContext && context.parentNode || context),
                dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || .1;
                if (outermost) {
                    outermostContext = context !== document && context;
                    cachedruns = matcherCachedRuns
                }
                for (; (elem = elems[i]) != null; i++) {
                    if (byElement && elem) {
                        j = 0;
                        while (matcher = elementMatchers[j++]) {
                            if (matcher(elem, context, xml)) {
                                results.push(elem);
                                break
                            }
                        }
                        if (outermost) {
                            dirruns = dirrunsUnique;
                            cachedruns = ++matcherCachedRuns
                        }
                    }
                    if (bySet) {
                        if (elem = !matcher && elem) {
                            matchedCount--
                        }
                        if (seed) {
                            unmatched.push(elem)
                        }
                    }
                }
                matchedCount += i;
                if (bySet && i !== matchedCount) {
                    j = 0;
                    while (matcher = setMatchers[j++]) {
                        matcher(unmatched, setMatched, context, xml)
                    }
                    if (seed) {
                        if (matchedCount > 0) {
                            while (i--) {
                                if (! (unmatched[i] || setMatched[i])) {
                                    setMatched[i] = pop.call(results)
                                }
                            }
                        }
                        setMatched = condense(setMatched)
                    }
                    push.apply(results, setMatched);
                    if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
                        Sizzle.uniqueSort(results)
                    }
                }
                if (outermost) {
                    dirruns = dirrunsUnique;
                    outermostContext = contextBackup
                }
                return unmatched
            };
            return bySet ? markFunction(superMatcher) : superMatcher
        }
        compile = Sizzle.compile = function(selector, group) {
            var i, setMatchers = [],
            elementMatchers = [],
            cached = compilerCache[selector + " "];
            if (!cached) {
                if (!group) {
                    group = tokenize(selector)
                }
                i = group.length;
                while (i--) {
                    cached = matcherFromTokens(group[i]);
                    if (cached[expando]) {
                        setMatchers.push(cached)
                    } else {
                        elementMatchers.push(cached)
                    }
                }
                cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers))
            }
            return cached
        };
        function multipleContexts(selector, contexts, results) {
            var i = 0,
            len = contexts.length;
            for (; i < len; i++) {
                Sizzle(selector, contexts[i], results)
            }
            return results
        }
        function select(selector, context, results, seed) {
            var i, tokens, token, type, find, match = tokenize(selector);
            if (!seed) {
                if (match.length === 1) {
                    tokens = match[0] = match[0].slice(0);
                    if (tokens.length > 2 && (token = tokens[0]).type === "ID" && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
                        context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
                        if (!context) {
                            return results
                        }
                        selector = selector.slice(tokens.shift().value.length)
                    }
                    i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
                    while (i--) {
                        token = tokens[i];
                        if (Expr.relative[type = token.type]) {
                            break
                        }
                        if (find = Expr.find[type]) {
                            if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && context.parentNode || context)) {
                                tokens.splice(i, 1);
                                selector = seed.length && toSelector(tokens);
                                if (!selector) {
                                    push.apply(results, seed);
                                    return results
                                }
                                break
                            }
                        }
                    }
                }
            }
            compile(selector, match)(seed, context, !documentIsHTML, results, rsibling.test(selector));
            return results
        }
        support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
        support.detectDuplicates = hasDuplicate;
        setDocument();
        support.sortDetached = assert(function(div1) {
            return div1.compareDocumentPosition(document.createElement("div")) & 1
        });
        if (!assert(function(div) {
            div.innerHTML = "<a href='#'></a>";
            return div.firstChild.getAttribute("href") === "#"
        })) {
            addHandle("type|href|height|width",
            function(elem, name, isXML) {
                if (!isXML) {
                    return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2)
                }
            })
        }
        if (!support.attributes || !assert(function(div) {
            div.innerHTML = "<input/>";
            div.firstChild.setAttribute("value", "");
            return div.firstChild.getAttribute("value") === ""
        })) {
            addHandle("value",
            function(elem, name, isXML) {
                if (!isXML && elem.nodeName.toLowerCase() === "input") {
                    return elem.defaultValue
                }
            })
        }
        if (!assert(function(div) {
            return div.getAttribute("disabled") == null
        })) {
            addHandle(booleans,
            function(elem, name, isXML) {
                var val;
                if (!isXML) {
                    return (val = elem.getAttributeNode(name)) && val.specified ? val.value: elem[name] === true ? name.toLowerCase() : null
                }
            })
        }
        jQuery.find = Sizzle;
        jQuery.expr = Sizzle.selectors;
        jQuery.expr[":"] = jQuery.expr.pseudos;
        jQuery.unique = Sizzle.uniqueSort;
        jQuery.text = Sizzle.getText;
        jQuery.isXMLDoc = Sizzle.isXML;
        jQuery.contains = Sizzle.contains
    })(window);
    var optionsCache = {};
    function createOptions(options) {
        var object = optionsCache[options] = {};
        jQuery.each(options.match(core_rnotwhite) || [],
        function(_, flag) {
            object[flag] = true
        });
        return object
    }
    jQuery.Callbacks = function(options) {
        options = typeof options === "string" ? optionsCache[options] || createOptions(options) : jQuery.extend({},
        options);
        var firing, memory, fired, firingLength, firingIndex, firingStart, list = [],
        stack = !options.once && [],
        fire = function(data) {
            memory = options.memory && data;
            fired = true;
            firingIndex = firingStart || 0;
            firingStart = 0;
            firingLength = list.length;
            firing = true;
            for (; list && firingIndex < firingLength; firingIndex++) {
                if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
                    memory = false;
                    break
                }
            }
            firing = false;
            if (list) {
                if (stack) {
                    if (stack.length) {
                        fire(stack.shift())
                    }
                } else if (memory) {
                    list = []
                } else {
                    self.disable()
                }
            }
        },
        self = {
            add: function() {
                if (list) {
                    var start = list.length; (function add(args) {
                        jQuery.each(args,
                        function(_, arg) {
                            var type = jQuery.type(arg);
                            if (type === "function") {
                                if (!options.unique || !self.has(arg)) {
                                    list.push(arg)
                                }
                            } else if (arg && arg.length && type !== "string") {
                                add(arg)
                            }
                        })
                    })(arguments);
                    if (firing) {
                        firingLength = list.length
                    } else if (memory) {
                        firingStart = start;
                        fire(memory)
                    }
                }
                return this
            },
            remove: function() {
                if (list) {
                    jQuery.each(arguments,
                    function(_, arg) {
                        var index;
                        while ((index = jQuery.inArray(arg, list, index)) > -1) {
                            list.splice(index, 1);
                            if (firing) {
                                if (index <= firingLength) {
                                    firingLength--
                                }
                                if (index <= firingIndex) {
                                    firingIndex--
                                }
                            }
                        }
                    })
                }
                return this
            },
            has: function(fn) {
                return fn ? jQuery.inArray(fn, list) > -1 : !!(list && list.length)
            },
            empty: function() {
                list = [];
                firingLength = 0;
                return this
            },
            disable: function() {
                list = stack = memory = undefined;
                return this
            },
            disabled: function() {
                return ! list
            },
            lock: function() {
                stack = undefined;
                if (!memory) {
                    self.disable()
                }
                return this
            },
            locked: function() {
                return ! stack
            },
            fireWith: function(context, args) {
                if (list && (!fired || stack)) {
                    args = args || [];
                    args = [context, args.slice ? args.slice() : args];
                    if (firing) {
                        stack.push(args)
                    } else {
                        fire(args)
                    }
                }
                return this
            },
            fire: function() {
                self.fireWith(this, arguments);
                return this
            },
            fired: function() {
                return !! fired
            }
        };
        return self
    };
    jQuery.extend({
        Deferred: function(func) {
            var tuples = [["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")]],
            state = "pending",
            promise = {
                state: function() {
                    return state
                },
                always: function() {
                    deferred.done(arguments).fail(arguments);
                    return this
                },
                then: function() {
                    var fns = arguments;
                    return jQuery.Deferred(function(newDefer) {
                        jQuery.each(tuples,
                        function(i, tuple) {
                            var action = tuple[0],
                            fn = jQuery.isFunction(fns[i]) && fns[i];
                            deferred[tuple[1]](function() {
                                var returned = fn && fn.apply(this, arguments);
                                if (returned && jQuery.isFunction(returned.promise)) {
                                    returned.promise().done(newDefer.resolve).fail(newDefer.reject).progress(newDefer.notify)
                                } else {
                                    newDefer[action + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments)
                                }
                            })
                        });
                        fns = null
                    }).promise()
                },
                promise: function(obj) {
                    return obj != null ? jQuery.extend(obj, promise) : promise
                }
            },
            deferred = {};
            promise.pipe = promise.then;
            jQuery.each(tuples,
            function(i, tuple) {
                var list = tuple[2],
                stateString = tuple[3];
                promise[tuple[1]] = list.add;
                if (stateString) {
                    list.add(function() {
                        state = stateString
                    },
                    tuples[i ^ 1][2].disable, tuples[2][2].lock)
                }
                deferred[tuple[0]] = function() {
                    deferred[tuple[0] + "With"](this === deferred ? promise: this, arguments);
                    return this
                };
                deferred[tuple[0] + "With"] = list.fireWith
            });
            promise.promise(deferred);
            if (func) {
                func.call(deferred, deferred)
            }
            return deferred
        },
        when: function(subordinate) {
            var i = 0,
            resolveValues = core_slice.call(arguments),
            length = resolveValues.length,
            remaining = length !== 1 || subordinate && jQuery.isFunction(subordinate.promise) ? length: 0,
            deferred = remaining === 1 ? subordinate: jQuery.Deferred(),
            updateFunc = function(i, contexts, values) {
                return function(value) {
                    contexts[i] = this;
                    values[i] = arguments.length > 1 ? core_slice.call(arguments) : value;
                    if (values === progressValues) {
                        deferred.notifyWith(contexts, values)
                    } else if (!--remaining) {
                        deferred.resolveWith(contexts, values)
                    }
                }
            },
            progressValues,
            progressContexts,
            resolveContexts;
            if (length > 1) {
                progressValues = new Array(length);
                progressContexts = new Array(length);
                resolveContexts = new Array(length);
                for (; i < length; i++) {
                    if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
                        resolveValues[i].promise().done(updateFunc(i, resolveContexts, resolveValues)).fail(deferred.reject).progress(updateFunc(i, progressContexts, progressValues))
                    } else {--remaining
                    }
                }
            }
            if (!remaining) {
                deferred.resolveWith(resolveContexts, resolveValues)
            }
            return deferred.promise()
        }
    });
    jQuery.support = function(support) {
        var all, a, input, select, fragment, opt, eventName, isSupported, i, div = document.createElement("div");
        div.setAttribute("className", "t");
        div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
        all = div.getElementsByTagName("*") || [];
        a = div.getElementsByTagName("a")[0];
        if (!a || !a.style || !all.length) {
            return support
        }
        select = document.createElement("select");
        opt = select.appendChild(document.createElement("option"));
        input = div.getElementsByTagName("input")[0];
        a.style.cssText = "top:1px;float:left;opacity:.5";
        support.getSetAttribute = div.className !== "t";
        support.leadingWhitespace = div.firstChild.nodeType === 3;
        support.tbody = !div.getElementsByTagName("tbody").length;
        support.htmlSerialize = !!div.getElementsByTagName("link").length;
        support.style = /top/.test(a.getAttribute("style"));
        support.hrefNormalized = a.getAttribute("href") === "/a";
        support.opacity = /^0.5/.test(a.style.opacity);
        support.cssFloat = !!a.style.cssFloat;
        support.checkOn = !!input.value;
        support.optSelected = opt.selected;
        support.enctype = !!document.createElement("form").enctype;
        support.html5Clone = document.createElement("nav").cloneNode(true).outerHTML !== "<:nav></:nav>";
        support.inlineBlockNeedsLayout = false;
        support.shrinkWrapBlocks = false;
        support.pixelPosition = false;
        support.deleteExpando = true;
        support.noCloneEvent = true;
        support.reliableMarginRight = true;
        support.boxSizingReliable = true;
        input.checked = true;
        support.noCloneChecked = input.cloneNode(true).checked;
        select.disabled = true;
        support.optDisabled = !opt.disabled;
        try {
            delete div.test
        } catch(e) {
            support.deleteExpando = false
        }
        input = document.createElement("input");
        input.setAttribute("value", "");
        support.input = input.getAttribute("value") === "";
        input.value = "t";
        input.setAttribute("type", "radio");
        support.radioValue = input.value === "t";
        input.setAttribute("checked", "t");
        input.setAttribute("name", "t");
        fragment = document.createDocumentFragment();
        fragment.appendChild(input);
        support.appendChecked = input.checked;
        support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
        if (div.attachEvent) {
            div.attachEvent("onclick",
            function() {
                support.noCloneEvent = false
            });
            div.cloneNode(true).click()
        }
        for (i in {
            submit: true,
            change: true,
            focusin: true
        }) {
            div.setAttribute(eventName = "on" + i, "t");
            support[i + "Bubbles"] = eventName in window || div.attributes[eventName].expando === false
        }
        div.style.backgroundClip = "content-box";
        div.cloneNode(true).style.backgroundClip = "";
        support.clearCloneStyle = div.style.backgroundClip === "content-box";
        for (i in jQuery(support)) {
            break
        }
        support.ownLast = i !== "0";
        jQuery(function() {
            var container, marginDiv, tds, divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
            body = document.getElementsByTagName("body")[0];
            if (!body) {
                return
            }
            container = document.createElement("div");
            container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
            body.appendChild(container).appendChild(div);
            div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
            tds = div.getElementsByTagName("td");
            tds[0].style.cssText = "padding:0;margin:0;border:0;display:none";
            isSupported = tds[0].offsetHeight === 0;
            tds[0].style.display = "";
            tds[1].style.display = "none";
            support.reliableHiddenOffsets = isSupported && tds[0].offsetHeight === 0;
            div.innerHTML = "";
            div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
            jQuery.swap(body, body.style.zoom != null ? {
                zoom: 1
            }: {},
            function() {
                support.boxSizing = div.offsetWidth === 4
            });
            if (window.getComputedStyle) {
                support.pixelPosition = (window.getComputedStyle(div, null) || {}).top !== "1%";
                support.boxSizingReliable = (window.getComputedStyle(div, null) || {
                    width: "4px"
                }).width === "4px";
                marginDiv = div.appendChild(document.createElement("div"));
                marginDiv.style.cssText = div.style.cssText = divReset;
                marginDiv.style.marginRight = marginDiv.style.width = "0";
                div.style.width = "1px";
                support.reliableMarginRight = !parseFloat((window.getComputedStyle(marginDiv, null) || {}).marginRight)
            }
            if (typeof div.style.zoom !== core_strundefined) {
                div.innerHTML = "";
                div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
                support.inlineBlockNeedsLayout = div.offsetWidth === 3;
                div.style.display = "block";
                div.innerHTML = "<div></div>";
                div.firstChild.style.width = "5px";
                support.shrinkWrapBlocks = div.offsetWidth !== 3;
                if (support.inlineBlockNeedsLayout) {
                    body.style.zoom = 1
                }
            }
            body.removeChild(container);
            container = div = tds = marginDiv = null
        });
        all = select = fragment = opt = a = input = null;
        return support
    } ({});
    var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
    rmultiDash = /([A-Z])/g;
    function internalData(elem, name, data, pvt) {
        if (!jQuery.acceptData(elem)) {
            return
        }
        var ret, thisCache, internalKey = jQuery.expando,
        isNode = elem.nodeType,
        cache = isNode ? jQuery.cache: elem,
        id = isNode ? elem[internalKey] : elem[internalKey] && internalKey;
        if ((!id || !cache[id] || !pvt && !cache[id].data) && data === undefined && typeof name === "string") {
            return
        }
        if (!id) {
            if (isNode) {
                id = elem[internalKey] = core_deletedIds.pop() || jQuery.guid++
            } else {
                id = internalKey
            }
        }
        if (!cache[id]) {
            cache[id] = isNode ? {}: {
                toJSON: jQuery.noop
            }
        }
        if (typeof name === "object" || typeof name === "function") {
            if (pvt) {
                cache[id] = jQuery.extend(cache[id], name)
            } else {
                cache[id].data = jQuery.extend(cache[id].data, name)
            }
        }
        thisCache = cache[id];
        if (!pvt) {
            if (!thisCache.data) {
                thisCache.data = {}
            }
            thisCache = thisCache.data
        }
        if (data !== undefined) {
            thisCache[jQuery.camelCase(name)] = data
        }
        if (typeof name === "string") {
            ret = thisCache[name];
            if (ret == null) {
                ret = thisCache[jQuery.camelCase(name)]
            }
        } else {
            ret = thisCache
        }
        return ret
    }
    function internalRemoveData(elem, name, pvt) {
        if (!jQuery.acceptData(elem)) {
            return
        }
        var thisCache, i, isNode = elem.nodeType,
        cache = isNode ? jQuery.cache: elem,
        id = isNode ? elem[jQuery.expando] : jQuery.expando;
        if (!cache[id]) {
            return
        }
        if (name) {
            thisCache = pvt ? cache[id] : cache[id].data;
            if (thisCache) {
                if (!jQuery.isArray(name)) {
                    if (name in thisCache) {
                        name = [name]
                    } else {
                        name = jQuery.camelCase(name);
                        if (name in thisCache) {
                            name = [name]
                        } else {
                            name = name.split(" ")
                        }
                    }
                } else {
                    name = name.concat(jQuery.map(name, jQuery.camelCase))
                }
                i = name.length;
                while (i--) {
                    delete thisCache[name[i]]
                }
                if (pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache)) {
                    return
                }
            }
        }
        if (!pvt) {
            delete cache[id].data;
            if (!isEmptyDataObject(cache[id])) {
                return
            }
        }
        if (isNode) {
            jQuery.cleanData([elem], true)
        } else if (jQuery.support.deleteExpando || cache != cache.window) {
            delete cache[id]
        } else {
            cache[id] = null
        }
    }
    jQuery.extend({
        cache: {},
        noData: {
            applet: true,
            embed: true,
            object: "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
        },
        hasData: function(elem) {
            elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]] : elem[jQuery.expando];
            return !! elem && !isEmptyDataObject(elem)
        },
        data: function(elem, name, data) {
            return internalData(elem, name, data)
        },
        removeData: function(elem, name) {
            return internalRemoveData(elem, name)
        },
        _data: function(elem, name, data) {
            return internalData(elem, name, data, true)
        },
        _removeData: function(elem, name) {
            return internalRemoveData(elem, name, true)
        },
        acceptData: function(elem) {
            if (elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9) {
                return false
            }
            var noData = elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()];
            return ! noData || noData !== true && elem.getAttribute("classid") === noData
        }
    });
    jQuery.fn.extend({
        data: function(key, value) {
            var attrs, name, data = null,
            i = 0,
            elem = this[0];
            if (key === undefined) {
                if (this.length) {
                    data = jQuery.data(elem);
                    if (elem.nodeType === 1 && !jQuery._data(elem, "parsedAttrs")) {
                        attrs = elem.attributes;
                        for (; i < attrs.length; i++) {
                            name = attrs[i].name;
                            if (name.indexOf("data-") === 0) {
                                name = jQuery.camelCase(name.slice(5));
                                dataAttr(elem, name, data[name])
                            }
                        }
                        jQuery._data(elem, "parsedAttrs", true)
                    }
                }
                return data
            }
            if (typeof key === "object") {
                return this.each(function() {
                    jQuery.data(this, key)
                })
            }
            return arguments.length > 1 ? this.each(function() {
                jQuery.data(this, key, value)
            }) : elem ? dataAttr(elem, key, jQuery.data(elem, key)) : null
        },
        removeData: function(key) {
            return this.each(function() {
                jQuery.removeData(this, key)
            })
        }
    });
    function dataAttr(elem, key, data) {
        if (data === undefined && elem.nodeType === 1) {
            var name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();
            data = elem.getAttribute(name);
            if (typeof data === "string") {
                try {
                    data = data === "true" ? true: data === "false" ? false: data === "null" ? null: +data + "" === data ? +data: rbrace.test(data) ? jQuery.parseJSON(data) : data
                } catch(e) {}
                jQuery.data(elem, key, data)
            } else {
                data = undefined
            }
        }
        return data
    }
    function isEmptyDataObject(obj) {
        var name;
        for (name in obj) {
            if (name === "data" && jQuery.isEmptyObject(obj[name])) {
                continue
            }
            if (name !== "toJSON") {
                return false
            }
        }
        return true
    }
    jQuery.extend({
        queue: function(elem, type, data) {
            var queue;
            if (elem) {
                type = (type || "fx") + "queue";
                queue = jQuery._data(elem, type);
                if (data) {
                    if (!queue || jQuery.isArray(data)) {
                        queue = jQuery._data(elem, type, jQuery.makeArray(data))
                    } else {
                        queue.push(data)
                    }
                }
                return queue || []
            }
        },
        dequeue: function(elem, type) {
            type = type || "fx";
            var queue = jQuery.queue(elem, type),
            startLength = queue.length,
            fn = queue.shift(),
            hooks = jQuery._queueHooks(elem, type),
            next = function() {
                jQuery.dequeue(elem, type)
            };
            if (fn === "inprogress") {
                fn = queue.shift();
                startLength--
            }
            if (fn) {
                if (type === "fx") {
                    queue.unshift("inprogress")
                }
                delete hooks.stop;
                fn.call(elem, next, hooks)
            }
            if (!startLength && hooks) {
                hooks.empty.fire()
            }
        },
        _queueHooks: function(elem, type) {
            var key = type + "queueHooks";
            return jQuery._data(elem, key) || jQuery._data(elem, key, {
                empty: jQuery.Callbacks("once memory").add(function() {
                    jQuery._removeData(elem, type + "queue");
                    jQuery._removeData(elem, key)
                })
            })
        }
    });
    jQuery.fn.extend({
        queue: function(type, data) {
            var setter = 2;
            if (typeof type !== "string") {
                data = type;
                type = "fx";
                setter--
            }
            if (arguments.length < setter) {
                return jQuery.queue(this[0], type)
            }
            return data === undefined ? this: this.each(function() {
                var queue = jQuery.queue(this, type, data);
                jQuery._queueHooks(this, type);
                if (type === "fx" && queue[0] !== "inprogress") {
                    jQuery.dequeue(this, type)
                }
            })
        },
        dequeue: function(type) {
            return this.each(function() {
                jQuery.dequeue(this, type)
            })
        },
        delay: function(time, type) {
            time = jQuery.fx ? jQuery.fx.speeds[time] || time: time;
            type = type || "fx";
            return this.queue(type,
            function(next, hooks) {
                var timeout = setTimeout(next, time);
                hooks.stop = function() {
                    clearTimeout(timeout)
                }
            })
        },
        clearQueue: function(type) {
            return this.queue(type || "fx", [])
        },
        promise: function(type, obj) {
            var tmp, count = 1,
            defer = jQuery.Deferred(),
            elements = this,
            i = this.length,
            resolve = function() {
                if (!--count) {
                    defer.resolveWith(elements, [elements])
                }
            };
            if (typeof type !== "string") {
                obj = type;
                type = undefined
            }
            type = type || "fx";
            while (i--) {
                tmp = jQuery._data(elements[i], type + "queueHooks");
                if (tmp && tmp.empty) {
                    count++;
                    tmp.empty.add(resolve)
                }
            }
            resolve();
            return defer.promise(obj)
        }
    });
    var nodeHook, boolHook, rclass = /[\t\r\n\f]/g,
    rreturn = /\r/g,
    rfocusable = /^(?:input|select|textarea|button|object)$/i,
    rclickable = /^(?:a|area)$/i,
    ruseDefault = /^(?:checked|selected)$/i,
    getSetAttribute = jQuery.support.getSetAttribute,
    getSetInput = jQuery.support.input;
    jQuery.fn.extend({
        attr: function(name, value) {
            return jQuery.access(this, jQuery.attr, name, value, arguments.length > 1)
        },
        removeAttr: function(name) {
            return this.each(function() {
                jQuery.removeAttr(this, name)
            })
        },
        prop: function(name, value) {
            return jQuery.access(this, jQuery.prop, name, value, arguments.length > 1)
        },
        removeProp: function(name) {
            name = jQuery.propFix[name] || name;
            return this.each(function() {
                try {
                    this[name] = undefined;
                    delete this[name]
                } catch(e) {}
            })
        },
        addClass: function(value) {
            var classes, elem, cur, clazz, j, i = 0,
            len = this.length,
            proceed = typeof value === "string" && value;
            if (jQuery.isFunction(value)) {
                return this.each(function(j) {
                    jQuery(this).addClass(value.call(this, j, this.className))
                })
            }
            if (proceed) {
                classes = (value || "").match(core_rnotwhite) || [];
                for (; i < len; i++) {
                    elem = this[i];
                    cur = elem.nodeType === 1 && (elem.className ? (" " + elem.className + " ").replace(rclass, " ") : " ");
                    if (cur) {
                        j = 0;
                        while (clazz = classes[j++]) {
                            if (cur.indexOf(" " + clazz + " ") < 0) {
                                cur += clazz + " "
                            }
                        }
                        elem.className = jQuery.trim(cur)
                    }
                }
            }
            return this
        },
        removeClass: function(value) {
            var classes, elem, cur, clazz, j, i = 0,
            len = this.length,
            proceed = arguments.length === 0 || typeof value === "string" && value;
            if (jQuery.isFunction(value)) {
                return this.each(function(j) {
                    jQuery(this).removeClass(value.call(this, j, this.className))
                })
            }
            if (proceed) {
                classes = (value || "").match(core_rnotwhite) || [];
                for (; i < len; i++) {
                    elem = this[i];
                    cur = elem.nodeType === 1 && (elem.className ? (" " + elem.className + " ").replace(rclass, " ") : "");
                    if (cur) {
                        j = 0;
                        while (clazz = classes[j++]) {
                            while (cur.indexOf(" " + clazz + " ") >= 0) {
                                cur = cur.replace(" " + clazz + " ", " ")
                            }
                        }
                        elem.className = value ? jQuery.trim(cur) : ""
                    }
                }
            }
            return this
        },
        toggleClass: function(value, stateVal) {
            var type = typeof value;
            if (typeof stateVal === "boolean" && type === "string") {
                return stateVal ? this.addClass(value) : this.removeClass(value)
            }
            if (jQuery.isFunction(value)) {
                return this.each(function(i) {
                    jQuery(this).toggleClass(value.call(this, i, this.className, stateVal), stateVal)
                })
            }
            return this.each(function() {
                if (type === "string") {
                    var className, i = 0,
                    self = jQuery(this),
                    classNames = value.match(core_rnotwhite) || [];
                    while (className = classNames[i++]) {
                        if (self.hasClass(className)) {
                            self.removeClass(className)
                        } else {
                            self.addClass(className)
                        }
                    }
                } else if (type === core_strundefined || type === "boolean") {
                    if (this.className) {
                        jQuery._data(this, "__className__", this.className)
                    }
                    this.className = this.className || value === false ? "": jQuery._data(this, "__className__") || ""
                }
            })
        },
        hasClass: function(selector) {
            var className = " " + selector + " ",
            i = 0,
            l = this.length;
            for (; i < l; i++) {
                if (this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) >= 0) {
                    return true
                }
            }
            return false
        },
        val: function(value) {
            var ret, hooks, isFunction, elem = this[0];
            if (!arguments.length) {
                if (elem) {
                    hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
                    if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
                        return ret
                    }
                    ret = elem.value;
                    return typeof ret === "string" ? ret.replace(rreturn, "") : ret == null ? "": ret
                }
                return
            }
            isFunction = jQuery.isFunction(value);
            return this.each(function(i) {
                var val;
                if (this.nodeType !== 1) {
                    return
                }
                if (isFunction) {
                    val = value.call(this, i, jQuery(this).val())
                } else {
                    val = value
                }
                if (val == null) {
                    val = ""
                } else if (typeof val === "number") {
                    val += ""
                } else if (jQuery.isArray(val)) {
                    val = jQuery.map(val,
                    function(value) {
                        return value == null ? "": value + ""
                    })
                }
                hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
                if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
                    this.value = val
                }
            })
        }
    });
    jQuery.extend({
        valHooks: {
            option: {
                get: function(elem) {
                    var val = jQuery.find.attr(elem, "value");
                    return val != null ? val: elem.text
                }
            },
            select: {
                get: function(elem) {
                    var value, option, options = elem.options,
                    index = elem.selectedIndex,
                    one = elem.type === "select-one" || index < 0,
                    values = one ? null: [],
                    max = one ? index + 1 : options.length,
                    i = index < 0 ? max: one ? index: 0;
                    for (; i < max; i++) {
                        option = options[i];
                        if ((option.selected || i === index) && (jQuery.support.optDisabled ? !option.disabled: option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {
                            value = jQuery(option).val();
                            if (one) {
                                return value
                            }
                            values.push(value)
                        }
                    }
                    return values
                },
                set: function(elem, value) {
                    var optionSet, option, options = elem.options,
                    values = jQuery.makeArray(value),
                    i = options.length;
                    while (i--) {
                        option = options[i];
                        if (option.selected = jQuery.inArray(jQuery(option).val(), values) >= 0) {
                            optionSet = true
                        }
                    }
                    if (!optionSet) {
                        elem.selectedIndex = -1
                    }
                    return values
                }
            }
        },
        attr: function(elem, name, value) {
            var hooks, ret, nType = elem.nodeType;
            if (!elem || nType === 3 || nType === 8 || nType === 2) {
                return
            }
            if (typeof elem.getAttribute === core_strundefined) {
                return jQuery.prop(elem, name, value)
            }
            if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
                name = name.toLowerCase();
                hooks = jQuery.attrHooks[name] || (jQuery.expr.match.bool.test(name) ? boolHook: nodeHook)
            }
            if (value !== undefined) {
                if (value === null) {
                    jQuery.removeAttr(elem, name)
                } else if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
                    return ret
                } else {
                    elem.setAttribute(name, value + "");
                    return value
                }
            } else if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
                return ret
            } else {
                ret = jQuery.find.attr(elem, name);
                return ret == null ? undefined: ret
            }
        },
        removeAttr: function(elem, value) {
            var name, propName, i = 0,
            attrNames = value && value.match(core_rnotwhite);
            if (attrNames && elem.nodeType === 1) {
                while (name = attrNames[i++]) {
                    propName = jQuery.propFix[name] || name;
                    if (jQuery.expr.match.bool.test(name)) {
                        if (getSetInput && getSetAttribute || !ruseDefault.test(name)) {
                            elem[propName] = false
                        } else {
                            elem[jQuery.camelCase("default-" + name)] = elem[propName] = false
                        }
                    } else {
                        jQuery.attr(elem, name, "")
                    }
                    elem.removeAttribute(getSetAttribute ? name: propName)
                }
            }
        },
        attrHooks: {
            type: {
                set: function(elem, value) {
                    if (!jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input")) {
                        var val = elem.value;
                        elem.setAttribute("type", value);
                        if (val) {
                            elem.value = val
                        }
                        return value
                    }
                }
            }
        },
        propFix: {
            "for": "htmlFor",
            "class": "className"
        },
        prop: function(elem, name, value) {
            var ret, hooks, notxml, nType = elem.nodeType;
            if (!elem || nType === 3 || nType === 8 || nType === 2) {
                return
            }
            notxml = nType !== 1 || !jQuery.isXMLDoc(elem);
            if (notxml) {
                name = jQuery.propFix[name] || name;
                hooks = jQuery.propHooks[name]
            }
            if (value !== undefined) {
                return hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined ? ret: elem[name] = value
            } else {
                return hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null ? ret: elem[name]
            }
        },
        propHooks: {
            tabIndex: {
                get: function(elem) {
                    var tabindex = jQuery.find.attr(elem, "tabindex");
                    return tabindex ? parseInt(tabindex, 10) : rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href ? 0 : -1
                }
            }
        }
    });
    boolHook = {
        set: function(elem, value, name) {
            if (value === false) {
                jQuery.removeAttr(elem, name)
            } else if (getSetInput && getSetAttribute || !ruseDefault.test(name)) {
                elem.setAttribute(!getSetAttribute && jQuery.propFix[name] || name, name)
            } else {
                elem[jQuery.camelCase("default-" + name)] = elem[name] = true
            }
            return name
        }
    };
    jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g),
    function(i, name) {
        var getter = jQuery.expr.attrHandle[name] || jQuery.find.attr;
        jQuery.expr.attrHandle[name] = getSetInput && getSetAttribute || !ruseDefault.test(name) ?
        function(elem, name, isXML) {
            var fn = jQuery.expr.attrHandle[name],
            ret = isXML ? undefined: (jQuery.expr.attrHandle[name] = undefined) != getter(elem, name, isXML) ? name.toLowerCase() : null;
            jQuery.expr.attrHandle[name] = fn;
            return ret
        }: function(elem, name, isXML) {
            return isXML ? undefined: elem[jQuery.camelCase("default-" + name)] ? name.toLowerCase() : null
        }
    });
    if (!getSetInput || !getSetAttribute) {
        jQuery.attrHooks.value = {
            set: function(elem, value, name) {
                if (jQuery.nodeName(elem, "input")) {
                    elem.defaultValue = value
                } else {
                    return nodeHook && nodeHook.set(elem, value, name)
                }
            }
        }
    }
    if (!getSetAttribute) {
        nodeHook = {
            set: function(elem, value, name) {
                var ret = elem.getAttributeNode(name);
                if (!ret) {
                    elem.setAttributeNode(ret = elem.ownerDocument.createAttribute(name))
                }
                ret.value = value += "";
                return name === "value" || value === elem.getAttribute(name) ? value: undefined
            }
        };
        jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = function(elem, name, isXML) {
            var ret;
            return isXML ? undefined: (ret = elem.getAttributeNode(name)) && ret.value !== "" ? ret.value: null
        };
        jQuery.valHooks.button = {
            get: function(elem, name) {
                var ret = elem.getAttributeNode(name);
                return ret && ret.specified ? ret.value: undefined
            },
            set: nodeHook.set
        };
        jQuery.attrHooks.contenteditable = {
            set: function(elem, value, name) {
                nodeHook.set(elem, value === "" ? false: value, name)
            }
        };
        jQuery.each(["width", "height"],
        function(i, name) {
            jQuery.attrHooks[name] = {
                set: function(elem, value) {
                    if (value === "") {
                        elem.setAttribute(name, "auto");
                        return value
                    }
                }
            }
        })
    }
    if (!jQuery.support.hrefNormalized) {
        jQuery.each(["href", "src"],
        function(i, name) {
            jQuery.propHooks[name] = {
                get: function(elem) {
                    return elem.getAttribute(name, 4)
                }
            }
        })
    }
    if (!jQuery.support.style) {
        jQuery.attrHooks.style = {
            get: function(elem) {
                return elem.style.cssText || undefined
            },
            set: function(elem, value) {
                return elem.style.cssText = value + ""
            }
        }
    }
    if (!jQuery.support.optSelected) {
        jQuery.propHooks.selected = {
            get: function(elem) {
                var parent = elem.parentNode;
                if (parent) {
                    parent.selectedIndex;
                    if (parent.parentNode) {
                        parent.parentNode.selectedIndex
                    }
                }
                return null
            }
        }
    }
    jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"],
    function() {
        jQuery.propFix[this.toLowerCase()] = this
    });
    if (!jQuery.support.enctype) {
        jQuery.propFix.enctype = "encoding"
    }
    jQuery.each(["radio", "checkbox"],
    function() {
        jQuery.valHooks[this] = {
            set: function(elem, value) {
                if (jQuery.isArray(value)) {
                    return elem.checked = jQuery.inArray(jQuery(elem).val(), value) >= 0
                }
            }
        };
        if (!jQuery.support.checkOn) {
            jQuery.valHooks[this].get = function(elem) {
                return elem.getAttribute("value") === null ? "on": elem.value
            }
        }
    });
    var rformElems = /^(?:input|select|textarea)$/i,
    rkeyEvent = /^key/,
    rmouseEvent = /^(?:mouse|contextmenu)|click/,
    rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
    rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
    function returnTrue() {
        return true
    }
    function returnFalse() {
        return false
    }
    function safeActiveElement() {
        try {
            return document.activeElement
        } catch(err) {}
    }
    jQuery.event = {
        global: {},
        add: function(elem, types, handler, data, selector) {
            var tmp, events, t, handleObjIn, special, eventHandle, handleObj, handlers, type, namespaces, origType, elemData = jQuery._data(elem);
            if (!elemData) {
                return
            }
            if (handler.handler) {
                handleObjIn = handler;
                handler = handleObjIn.handler;
                selector = handleObjIn.selector
            }
            if (!handler.guid) {
                handler.guid = jQuery.guid++
            }
            if (! (events = elemData.events)) {
                events = elemData.events = {}
            }
            if (! (eventHandle = elemData.handle)) {
                eventHandle = elemData.handle = function(e) {
                    return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined
                };
                eventHandle.elem = elem
            }
            types = (types || "").match(core_rnotwhite) || [""];
            t = types.length;
            while (t--) {
                tmp = rtypenamespace.exec(types[t]) || [];
                type = origType = tmp[1];
                namespaces = (tmp[2] || "").split(".").sort();
                if (!type) {
                    continue
                }
                special = jQuery.event.special[type] || {};
                type = (selector ? special.delegateType: special.bindType) || type;
                special = jQuery.event.special[type] || {};
                handleObj = jQuery.extend({
                    type: type,
                    origType: origType,
                    data: data,
                    handler: handler,
                    guid: handler.guid,
                    selector: selector,
                    needsContext: selector && jQuery.expr.match.needsContext.test(selector),
                    namespace: namespaces.join(".")
                },
                handleObjIn);
                if (! (handlers = events[type])) {
                    handlers = events[type] = [];
                    handlers.delegateCount = 0;
                    if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
                        if (elem.addEventListener) {
                            elem.addEventListener(type, eventHandle, false)
                        } else if (elem.attachEvent) {
                            elem.attachEvent("on" + type, eventHandle)
                        }
                    }
                }
                if (special.add) {
                    special.add.call(elem, handleObj);
                    if (!handleObj.handler.guid) {
                        handleObj.handler.guid = handler.guid
                    }
                }
                if (selector) {
                    handlers.splice(handlers.delegateCount++, 0, handleObj)
                } else {
                    handlers.push(handleObj)
                }
                jQuery.event.global[type] = true
            }
            elem = null
        },
        remove: function(elem, types, handler, selector, mappedTypes) {
            var j, handleObj, tmp, origCount, t, events, special, handlers, type, namespaces, origType, elemData = jQuery.hasData(elem) && jQuery._data(elem);
            if (!elemData || !(events = elemData.events)) {
                return
            }
            types = (types || "").match(core_rnotwhite) || [""];
            t = types.length;
            while (t--) {
                tmp = rtypenamespace.exec(types[t]) || [];
                type = origType = tmp[1];
                namespaces = (tmp[2] || "").split(".").sort();
                if (!type) {
                    for (type in events) {
                        jQuery.event.remove(elem, type + types[t], handler, selector, true)
                    }
                    continue
                }
                special = jQuery.event.special[type] || {};
                type = (selector ? special.delegateType: special.bindType) || type;
                handlers = events[type] || [];
                tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
                origCount = j = handlers.length;
                while (j--) {
                    handleObj = handlers[j];
                    if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
                        handlers.splice(j, 1);
                        if (handleObj.selector) {
                            handlers.delegateCount--
                        }
                        if (special.remove) {
                            special.remove.call(elem, handleObj)
                        }
                    }
                }
                if (origCount && !handlers.length) {
                    if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
                        jQuery.removeEvent(elem, type, elemData.handle)
                    }
                    delete events[type]
                }
            }
            if (jQuery.isEmptyObject(events)) {
                delete elemData.handle;
                jQuery._removeData(elem, "events")
            }
        },
        trigger: function(event, data, elem, onlyHandlers) {
            var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [elem || document],
            type = core_hasOwn.call(event, "type") ? event.type: event,
            namespaces = core_hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
            cur = tmp = elem = elem || document;
            if (elem.nodeType === 3 || elem.nodeType === 8) {
                return
            }
            if (rfocusMorph.test(type + jQuery.event.triggered)) {
                return
            }
            if (type.indexOf(".") >= 0) {
                namespaces = type.split(".");
                type = namespaces.shift();
                namespaces.sort()
            }
            ontype = type.indexOf(":") < 0 && "on" + type;
            event = event[jQuery.expando] ? event: new jQuery.Event(type, typeof event === "object" && event);
            event.isTrigger = onlyHandlers ? 2 : 3;
            event.namespace = namespaces.join(".");
            event.namespace_re = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
            event.result = undefined;
            if (!event.target) {
                event.target = elem
            }
            data = data == null ? [event] : jQuery.makeArray(data, [event]);
            special = jQuery.event.special[type] || {};
            if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
                return
            }
            if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
                bubbleType = special.delegateType || type;
                if (!rfocusMorph.test(bubbleType + type)) {
                    cur = cur.parentNode
                }
                for (; cur; cur = cur.parentNode) {
                    eventPath.push(cur);
                    tmp = cur
                }
                if (tmp === (elem.ownerDocument || document)) {
                    eventPath.push(tmp.defaultView || tmp.parentWindow || window)
                }
            }
            i = 0;
            while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
                event.type = i > 1 ? bubbleType: special.bindType || type;
                handle = (jQuery._data(cur, "events") || {})[event.type] && jQuery._data(cur, "handle");
                if (handle) {
                    handle.apply(cur, data)
                }
                handle = ontype && cur[ontype];
                if (handle && jQuery.acceptData(cur) && handle.apply && handle.apply(cur, data) === false) {
                    event.preventDefault()
                }
            }
            event.type = type;
            if (!onlyHandlers && !event.isDefaultPrevented()) {
                if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && jQuery.acceptData(elem)) {
                    if (ontype && elem[type] && !jQuery.isWindow(elem)) {
                        tmp = elem[ontype];
                        if (tmp) {
                            elem[ontype] = null
                        }
                        jQuery.event.triggered = type;
                        try {
                            elem[type]()
                        } catch(e) {}
                        jQuery.event.triggered = undefined;
                        if (tmp) {
                            elem[ontype] = tmp
                        }
                    }
                }
            }
            return event.result
        },
        dispatch: function(event) {
            event = jQuery.event.fix(event);
            var i, ret, handleObj, matched, j, handlerQueue = [],
            args = core_slice.call(arguments),
            handlers = (jQuery._data(this, "events") || {})[event.type] || [],
            special = jQuery.event.special[event.type] || {};
            args[0] = event;
            event.delegateTarget = this;
            if (special.preDispatch && special.preDispatch.call(this, event) === false) {
                return
            }
            handlerQueue = jQuery.event.handlers.call(this, event, handlers);
            i = 0;
            while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
                event.currentTarget = matched.elem;
                j = 0;
                while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
                    if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) {
                        event.handleObj = handleObj;
                        event.data = handleObj.data;
                        ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
                        if (ret !== undefined) {
                            if ((event.result = ret) === false) {
                                event.preventDefault();
                                event.stopPropagation()
                            }
                        }
                    }
                }
            }
            if (special.postDispatch) {
                special.postDispatch.call(this, event)
            }
            return event.result
        },
        handlers: function(event, handlers) {
            var sel, handleObj, matches, i, handlerQueue = [],
            delegateCount = handlers.delegateCount,
            cur = event.target;
            if (delegateCount && cur.nodeType && (!event.button || event.type !== "click")) {
                for (; cur != this; cur = cur.parentNode || this) {
                    if (cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click")) {
                        matches = [];
                        for (i = 0; i < delegateCount; i++) {
                            handleObj = handlers[i];
                            sel = handleObj.selector + " ";
                            if (matches[sel] === undefined) {
                                matches[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) >= 0 : jQuery.find(sel, this, null, [cur]).length
                            }
                            if (matches[sel]) {
                                matches.push(handleObj)
                            }
                        }
                        if (matches.length) {
                            handlerQueue.push({
                                elem: cur,
                                handlers: matches
                            })
                        }
                    }
                }
            }
            if (delegateCount < handlers.length) {
                handlerQueue.push({
                    elem: this,
                    handlers: handlers.slice(delegateCount)
                })
            }
            return handlerQueue
        },
        fix: function(event) {
            if (event[jQuery.expando]) {
                return event
            }
            var i, prop, copy, type = event.type,
            originalEvent = event,
            fixHook = this.fixHooks[type];
            if (!fixHook) {
                this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks: rkeyEvent.test(type) ? this.keyHooks: {}
            }
            copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;
            event = new jQuery.Event(originalEvent);
            i = copy.length;
            while (i--) {
                prop = copy[i];
                event[prop] = originalEvent[prop]
            }
            if (!event.target) {
                event.target = originalEvent.srcElement || document
            }
            if (event.target.nodeType === 3) {
                event.target = event.target.parentNode
            }
            event.metaKey = !!event.metaKey;
            return fixHook.filter ? fixHook.filter(event, originalEvent) : event
        },
        props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
        fixHooks: {},
        keyHooks: {
            props: "char charCode key keyCode".split(" "),
            filter: function(event, original) {
                if (event.which == null) {
                    event.which = original.charCode != null ? original.charCode: original.keyCode
                }
                return event
            }
        },
        mouseHooks: {
            props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
            filter: function(event, original) {
                var body, eventDoc, doc, button = original.button,
                fromElement = original.fromElement;
                if (event.pageX == null && original.clientX != null) {
                    eventDoc = event.target.ownerDocument || document;
                    doc = eventDoc.documentElement;
                    body = eventDoc.body;
                    event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
                    event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0)
                }
                if (!event.relatedTarget && fromElement) {
                    event.relatedTarget = fromElement === event.target ? original.toElement: fromElement
                }
                if (!event.which && button !== undefined) {
                    event.which = button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0
                }
                return event
            }
        },
        special: {
            load: {
                noBubble: true
            },
            focus: {
                trigger: function() {
                    if (this !== safeActiveElement() && this.focus) {
                        try {
                            this.focus();
                            return false
                        } catch(e) {}
                    }
                },
                delegateType: "focusin"
            },
            blur: {
                trigger: function() {
                    if (this === safeActiveElement() && this.blur) {
                        this.blur();
                        return false
                    }
                },
                delegateType: "focusout"
            },
            click: {
                trigger: function() {
                    if (jQuery.nodeName(this, "input") && this.type === "checkbox" && this.click) {
                        this.click();
                        return false
                    }
                },
                _default: function(event) {
                    return jQuery.nodeName(event.target, "a")
                }
            },
            beforeunload: {
                postDispatch: function(event) {
                    if (event.result !== undefined) {
                        event.originalEvent.returnValue = event.result
                    }
                }
            }
        },
        simulate: function(type, elem, event, bubble) {
            var e = jQuery.extend(new jQuery.Event, event, {
                type: type,
                isSimulated: true,
                originalEvent: {}
            });
            if (bubble) {
                jQuery.event.trigger(e, null, elem)
            } else {
                jQuery.event.dispatch.call(elem, e)
            }
            if (e.isDefaultPrevented()) {
                event.preventDefault()
            }
        }
    };
    jQuery.removeEvent = document.removeEventListener ?
    function(elem, type, handle) {
        if (elem.removeEventListener) {
            elem.removeEventListener(type, handle, false)
        }
    }: function(elem, type, handle) {
        var name = "on" + type;
        if (elem.detachEvent) {
            if (typeof elem[name] === core_strundefined) {
                elem[name] = null
            }
            elem.detachEvent(name, handle)
        }
    };
    jQuery.Event = function(src, props) {
        if (! (this instanceof jQuery.Event)) {
            return new jQuery.Event(src, props)
        }
        if (src && src.type) {
            this.originalEvent = src;
            this.type = src.type;
            this.isDefaultPrevented = src.defaultPrevented || src.returnValue === false || src.getPreventDefault && src.getPreventDefault() ? returnTrue: returnFalse
        } else {
            this.type = src
        }
        if (props) {
            jQuery.extend(this, props)
        }
        this.timeStamp = src && src.timeStamp || jQuery.now();
        this[jQuery.expando] = true
    };
    jQuery.Event.prototype = {
        isDefaultPrevented: returnFalse,
        isPropagationStopped: returnFalse,
        isImmediatePropagationStopped: returnFalse,
        preventDefault: function() {
            var e = this.originalEvent;
            this.isDefaultPrevented = returnTrue;
            if (!e) {
                return
            }
            if (e.preventDefault) {
                e.preventDefault()
            } else {
                e.returnValue = false
            }
        },
        stopPropagation: function() {
            var e = this.originalEvent;
            this.isPropagationStopped = returnTrue;
            if (!e) {
                return
            }
            if (e.stopPropagation) {
                e.stopPropagation()
            }
            e.cancelBubble = true
        },
        stopImmediatePropagation: function() {
            this.isImmediatePropagationStopped = returnTrue;
            this.stopPropagation()
        }
    };
    jQuery.each({
        mouseenter: "mouseover",
        mouseleave: "mouseout"
    },
    function(orig, fix) {
        jQuery.event.special[orig] = {
            delegateType: fix,
            bindType: fix,
            handle: function(event) {
                var ret, target = this,
                related = event.relatedTarget,
                handleObj = event.handleObj;
                if (!related || related !== target && !jQuery.contains(target, related)) {
                    event.type = handleObj.origType;
                    ret = handleObj.handler.apply(this, arguments);
                    event.type = fix
                }
                return ret
            }
        }
    });
    if (!jQuery.support.submitBubbles) {
        jQuery.event.special.submit = {
            setup: function() {
                if (jQuery.nodeName(this, "form")) {
                    return false
                }
                jQuery.event.add(this, "click._submit keypress._submit",
                function(e) {
                    var elem = e.target,
                    form = jQuery.nodeName(elem, "input") || jQuery.nodeName(elem, "button") ? elem.form: undefined;
                    if (form && !jQuery._data(form, "submitBubbles")) {
                        jQuery.event.add(form, "submit._submit",
                        function(event) {
                            event._submit_bubble = true
                        });
                        jQuery._data(form, "submitBubbles", true)
                    }
                })
            },
            postDispatch: function(event) {
                if (event._submit_bubble) {
                    delete event._submit_bubble;
                    if (this.parentNode && !event.isTrigger) {
                        jQuery.event.simulate("submit", this.parentNode, event, true)
                    }
                }
            },
            teardown: function() {
                if (jQuery.nodeName(this, "form")) {
                    return false
                }
                jQuery.event.remove(this, "._submit")
            }
        }
    }
    if (!jQuery.support.changeBubbles) {
        jQuery.event.special.change = {
            setup: function() {
                if (rformElems.test(this.nodeName)) {
                    if (this.type === "checkbox" || this.type === "radio") {
                        jQuery.event.add(this, "propertychange._change",
                        function(event) {
                            if (event.originalEvent.propertyName === "checked") {
                                this._just_changed = true
                            }
                        });
                        jQuery.event.add(this, "click._change",
                        function(event) {
                            if (this._just_changed && !event.isTrigger) {
                                this._just_changed = false
                            }
                            jQuery.event.simulate("change", this, event, true)
                        })
                    }
                    return false
                }
                jQuery.event.add(this, "beforeactivate._change",
                function(e) {
                    var elem = e.target;
                    if (rformElems.test(elem.nodeName) && !jQuery._data(elem, "changeBubbles")) {
                        jQuery.event.add(elem, "change._change",
                        function(event) {
                            if (this.parentNode && !event.isSimulated && !event.isTrigger) {
                                jQuery.event.simulate("change", this.parentNode, event, true)
                            }
                        });
                        jQuery._data(elem, "changeBubbles", true)
                    }
                })
            },
            handle: function(event) {
                var elem = event.target;
                if (this !== elem || event.isSimulated || event.isTrigger || elem.type !== "radio" && elem.type !== "checkbox") {
                    return event.handleObj.handler.apply(this, arguments)
                }
            },
            teardown: function() {
                jQuery.event.remove(this, "._change");
                return ! rformElems.test(this.nodeName)
            }
        }
    }
    if (!jQuery.support.focusinBubbles) {
        jQuery.each({
            focus: "focusin",
            blur: "focusout"
        },
        function(orig, fix) {
            var attaches = 0,
            handler = function(event) {
                jQuery.event.simulate(fix, event.target, jQuery.event.fix(event), true)
            };
            jQuery.event.special[fix] = {
                setup: function() {
                    if (attaches++===0) {
                        document.addEventListener(orig, handler, true)
                    }
                },
                teardown: function() {
                    if (--attaches === 0) {
                        document.removeEventListener(orig, handler, true)
                    }
                }
            }
        })
    }
    jQuery.fn.extend({
        on: function(types, selector, data, fn, one) {
            var type, origFn;
            if (typeof types === "object") {
                if (typeof selector !== "string") {
                    data = data || selector;
                    selector = undefined
                }
                for (type in types) {
                    this.on(type, selector, data, types[type], one)
                }
                return this
            }
            if (data == null && fn == null) {
                fn = selector;
                data = selector = undefined
            } else if (fn == null) {
                if (typeof selector === "string") {
                    fn = data;
                    data = undefined
                } else {
                    fn = data;
                    data = selector;
                    selector = undefined
                }
            }
            if (fn === false) {
                fn = returnFalse
            } else if (!fn) {
                return this
            }
            if (one === 1) {
                origFn = fn;
                fn = function(event) {
                    jQuery().off(event);
                    return origFn.apply(this, arguments)
                };
                fn.guid = origFn.guid || (origFn.guid = jQuery.guid++)
            }
            return this.each(function() {
                jQuery.event.add(this, types, fn, data, selector)
            })
        },
        one: function(types, selector, data, fn) {
            return this.on(types, selector, data, fn, 1)
        },
        off: function(types, selector, fn) {
            var handleObj, type;
            if (types && types.preventDefault && types.handleObj) {
                handleObj = types.handleObj;
                jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace: handleObj.origType, handleObj.selector, handleObj.handler);
                return this
            }
            if (typeof types === "object") {
                for (type in types) {
                    this.off(type, selector, types[type])
                }
                return this
            }
            if (selector === false || typeof selector === "function") {
                fn = selector;
                selector = undefined
            }
            if (fn === false) {
                fn = returnFalse
            }
            return this.each(function() {
                jQuery.event.remove(this, types, fn, selector)
            })
        },
        trigger: function(type, data) {
            return this.each(function() {
                jQuery.event.trigger(type, data, this)
            })
        },
        triggerHandler: function(type, data) {
            var elem = this[0];
            if (elem) {
                return jQuery.event.trigger(type, data, elem, true)
            }
        }
    });
    var isSimple = /^.[^:#\[\.,]*$/,
    rparentsprev = /^(?:parents|prev(?:Until|All))/,
    rneedsContext = jQuery.expr.match.needsContext,
    guaranteedUnique = {
        children: true,
        contents: true,
        next: true,
        prev: true
    };
    jQuery.fn.extend({
        find: function(selector) {
            var i, ret = [],
            self = this,
            len = self.length;
            if (typeof selector !== "string") {
                return this.pushStack(jQuery(selector).filter(function() {
                    for (i = 0; i < len; i++) {
                        if (jQuery.contains(self[i], this)) {
                            return true
                        }
                    }
                }))
            }
            for (i = 0; i < len; i++) {
                jQuery.find(selector, self[i], ret)
            }
            ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
            ret.selector = this.selector ? this.selector + " " + selector: selector;
            return ret
        },
        has: function(target) {
            var i, targets = jQuery(target, this),
            len = targets.length;
            return this.filter(function() {
                for (i = 0; i < len; i++) {
                    if (jQuery.contains(this, targets[i])) {
                        return true
                    }
                }
            })
        },
        not: function(selector) {
            return this.pushStack(winnow(this, selector || [], true))
        },
        filter: function(selector) {
            return this.pushStack(winnow(this, selector || [], false))
        },
        is: function(selector) {
            return !! winnow(this, typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length
        },
        closest: function(selectors, context) {
            var cur, i = 0,
            l = this.length,
            ret = [],
            pos = rneedsContext.test(selectors) || typeof selectors !== "string" ? jQuery(selectors, context || this.context) : 0;
            for (; i < l; i++) {
                for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
                    if (cur.nodeType < 11 && (pos ? pos.index(cur) > -1 : cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
                        cur = ret.push(cur);
                        break
                    }
                }
            }
            return this.pushStack(ret.length > 1 ? jQuery.unique(ret) : ret)
        },
        index: function(elem) {
            if (!elem) {
                return this[0] && this[0].parentNode ? this.first().prevAll().length: -1
            }
            if (typeof elem === "string") {
                return jQuery.inArray(this[0], jQuery(elem))
            }
            return jQuery.inArray(elem.jquery ? elem[0] : elem, this)
        },
        add: function(selector, context) {
            var set = typeof selector === "string" ? jQuery(selector, context) : jQuery.makeArray(selector && selector.nodeType ? [selector] : selector),
            all = jQuery.merge(this.get(), set);
            return this.pushStack(jQuery.unique(all))
        },
        addBack: function(selector) {
            return this.add(selector == null ? this.prevObject: this.prevObject.filter(selector))
        }
    });
    function sibling(cur, dir) {
        do {
            cur = cur[dir]
        } while ( cur && cur . nodeType !== 1 );
        return cur
    }
    jQuery.each({
        parent: function(elem) {
            var parent = elem.parentNode;
            return parent && parent.nodeType !== 11 ? parent: null
        },
        parents: function(elem) {
            return jQuery.dir(elem, "parentNode")
        },
        parentsUntil: function(elem, i, until) {
            return jQuery.dir(elem, "parentNode", until)
        },
        next: function(elem) {
            return sibling(elem, "nextSibling")
        },
        prev: function(elem) {
            return sibling(elem, "previousSibling")
        },
        nextAll: function(elem) {
            return jQuery.dir(elem, "nextSibling")
        },
        prevAll: function(elem) {
            return jQuery.dir(elem, "previousSibling")
        },
        nextUntil: function(elem, i, until) {
            return jQuery.dir(elem, "nextSibling", until)
        },
        prevUntil: function(elem, i, until) {
            return jQuery.dir(elem, "previousSibling", until)
        },
        siblings: function(elem) {
            return jQuery.sibling((elem.parentNode || {}).firstChild, elem)
        },
        children: function(elem) {
            return jQuery.sibling(elem.firstChild)
        },
        contents: function(elem) {
            return jQuery.nodeName(elem, "iframe") ? elem.contentDocument || elem.contentWindow.document: jQuery.merge([], elem.childNodes)
        }
    },
    function(name, fn) {
        jQuery.fn[name] = function(until, selector) {
            var ret = jQuery.map(this, fn, until);
            if (name.slice( - 5) !== "Until") {
                selector = until
            }
            if (selector && typeof selector === "string") {
                ret = jQuery.filter(selector, ret)
            }
            if (this.length > 1) {
                if (!guaranteedUnique[name]) {
                    ret = jQuery.unique(ret)
                }
                if (rparentsprev.test(name)) {
                    ret = ret.reverse()
                }
            }
            return this.pushStack(ret)
        }
    });
    jQuery.extend({
        filter: function(expr, elems, not) {
            var elem = elems[0];
            if (not) {
                expr = ":not(" + expr + ")"
            }
            return elems.length === 1 && elem.nodeType === 1 ? jQuery.find.matchesSelector(elem, expr) ? [elem] : [] : jQuery.find.matches(expr, jQuery.grep(elems,
            function(elem) {
                return elem.nodeType === 1
            }))
        },
        dir: function(elem, dir, until) {
            var matched = [],
            cur = elem[dir];
            while (cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery(cur).is(until))) {
                if (cur.nodeType === 1) {
                    matched.push(cur)
                }
                cur = cur[dir]
            }
            return matched
        },
        sibling: function(n, elem) {
            var r = [];
            for (; n; n = n.nextSibling) {
                if (n.nodeType === 1 && n !== elem) {
                    r.push(n)
                }
            }
            return r
        }
    });
    function winnow(elements, qualifier, not) {
        if (jQuery.isFunction(qualifier)) {
            return jQuery.grep(elements,
            function(elem, i) {
                return !! qualifier.call(elem, i, elem) !== not
            })
        }
        if (qualifier.nodeType) {
            return jQuery.grep(elements,
            function(elem) {
                return elem === qualifier !== not
            })
        }
        if (typeof qualifier === "string") {
            if (isSimple.test(qualifier)) {
                return jQuery.filter(qualifier, elements, not)
            }
            qualifier = jQuery.filter(qualifier, elements)
        }
        return jQuery.grep(elements,
        function(elem) {
            return jQuery.inArray(elem, qualifier) >= 0 !== not
        })
    }
    function createSafeFragment(document) {
        var list = nodeNames.split("|"),
        safeFrag = document.createDocumentFragment();
        if (safeFrag.createElement) {
            while (list.length) {
                safeFrag.createElement(list.pop())
            }
        }
        return safeFrag
    }
    var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
    rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
    rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
    rleadingWhitespace = /^\s+/,
    rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
    rtagName = /<([\w:]+)/,
    rtbody = /<tbody/i,
    rhtml = /<|&#?\w+;/,
    rnoInnerhtml = /<(?:script|style|link)/i,
    manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
    rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
    rscriptType = /^$|\/(?:java|ecma)script/i,
    rscriptTypeMasked = /^true\/(.*)/,
    rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
    wrapMap = {
        option: [1, "<select multiple='multiple'>", "</select>"],
        legend: [1, "<fieldset>", "</fieldset>"],
        area: [1, "<map>", "</map>"],
        param: [1, "<object>", "</object>"],
        thead: [1, "<table>", "</table>"],
        tr: [2, "<table><tbody>", "</tbody></table>"],
        col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
        td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
        _default: jQuery.support.htmlSerialize ? [0, "", ""] : [1, "X<div>", "</div>"]
    },
    safeFragment = createSafeFragment(document),
    fragmentDiv = safeFragment.appendChild(document.createElement("div"));
    wrapMap.optgroup = wrapMap.option;
    wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    wrapMap.th = wrapMap.td;
    jQuery.fn.extend({
        text: function(value) {
            return jQuery.access(this,
            function(value) {
                return value === undefined ? jQuery.text(this) : this.empty().append((this[0] && this[0].ownerDocument || document).createTextNode(value))
            },
            null, value, arguments.length)
        },
        append: function() {
            return this.domManip(arguments,
            function(elem) {
                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
                    var target = manipulationTarget(this, elem);
                    target.appendChild(elem)
                }
            })
        },
        prepend: function() {
            return this.domManip(arguments,
            function(elem) {
                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
                    var target = manipulationTarget(this, elem);
                    target.insertBefore(elem, target.firstChild)
                }
            })
        },
        before: function() {
            return this.domManip(arguments,
            function(elem) {
                if (this.parentNode) {
                    this.parentNode.insertBefore(elem, this)
                }
            })
        },
        after: function() {
            return this.domManip(arguments,
            function(elem) {
                if (this.parentNode) {
                    this.parentNode.insertBefore(elem, this.nextSibling)
                }
            })
        },
        remove: function(selector, keepData) {
            var elem, elems = selector ? jQuery.filter(selector, this) : this,
            i = 0;
            for (; (elem = elems[i]) != null; i++) {
                if (!keepData && elem.nodeType === 1) {
                    jQuery.cleanData(getAll(elem))
                }
                if (elem.parentNode) {
                    if (keepData && jQuery.contains(elem.ownerDocument, elem)) {
                        setGlobalEval(getAll(elem, "script"))
                    }
                    elem.parentNode.removeChild(elem)
                }
            }
            return this
        },
        empty: function() {
            var elem, i = 0;
            for (; (elem = this[i]) != null; i++) {
                if (elem.nodeType === 1) {
                    jQuery.cleanData(getAll(elem, false))
                }
                while (elem.firstChild) {
                    elem.removeChild(elem.firstChild)
                }
                if (elem.options && jQuery.nodeName(elem, "select")) {
                    elem.options.length = 0
                }
            }
            return this
        },
        clone: function(dataAndEvents, deepDataAndEvents) {
            dataAndEvents = dataAndEvents == null ? false: dataAndEvents;
            deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents: deepDataAndEvents;
            return this.map(function() {
                return jQuery.clone(this, dataAndEvents, deepDataAndEvents)
            })
        },
        html: function(value) {
            return jQuery.access(this,
            function(value) {
                var elem = this[0] || {},
                i = 0,
                l = this.length;
                if (value === undefined) {
                    return elem.nodeType === 1 ? elem.innerHTML.replace(rinlinejQuery, "") : undefined
                }
                if (typeof value === "string" && !rnoInnerhtml.test(value) && (jQuery.support.htmlSerialize || !rnoshimcache.test(value)) && (jQuery.support.leadingWhitespace || !rleadingWhitespace.test(value)) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
                    value = value.replace(rxhtmlTag, "<$1></$2>");
                    try {
                        for (; i < l; i++) {
                            elem = this[i] || {};
                            if (elem.nodeType === 1) {
                                jQuery.cleanData(getAll(elem, false));
                                elem.innerHTML = value
                            }
                        }
                        elem = 0
                    } catch(e) {}
                }
                if (elem) {
                    this.empty().append(value)
                }
            },
            null, value, arguments.length)
        },
        replaceWith: function() {
            var args = jQuery.map(this,
            function(elem) {
                return [elem.nextSibling, elem.parentNode]
            }),
            i = 0;
            this.domManip(arguments,
            function(elem) {
                var next = args[i++],
                parent = args[i++];
                if (parent) {
                    if (next && next.parentNode !== parent) {
                        next = this.nextSibling
                    }
                    jQuery(this).remove();
                    parent.insertBefore(elem, next)
                }
            },
            true);
            return i ? this: this.remove()
        },
        detach: function(selector) {
            return this.remove(selector, true)
        },
        domManip: function(args, callback, allowIntersection) {
            args = core_concat.apply([], args);
            var first, node, hasScripts, scripts, doc, fragment, i = 0,
            l = this.length,
            set = this,
            iNoClone = l - 1,
            value = args[0],
            isFunction = jQuery.isFunction(value);
            if (isFunction || !(l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test(value))) {
                return this.each(function(index) {
                    var self = set.eq(index);
                    if (isFunction) {
                        args[0] = value.call(this, index, self.html())
                    }
                    self.domManip(args, callback, allowIntersection)
                })
            }
            if (l) {
                fragment = jQuery.buildFragment(args, this[0].ownerDocument, false, !allowIntersection && this);
                first = fragment.firstChild;
                if (fragment.childNodes.length === 1) {
                    fragment = first
                }
                if (first) {
                    scripts = jQuery.map(getAll(fragment, "script"), disableScript);
                    hasScripts = scripts.length;
                    for (; i < l; i++) {
                        node = fragment;
                        if (i !== iNoClone) {
                            node = jQuery.clone(node, true, true);
                            if (hasScripts) {
                                jQuery.merge(scripts, getAll(node, "script"))
                            }
                        }
                        callback.call(this[i], node, i)
                    }
                    if (hasScripts) {
                        doc = scripts[scripts.length - 1].ownerDocument;
                        jQuery.map(scripts, restoreScript);
                        for (i = 0; i < hasScripts; i++) {
                            node = scripts[i];
                            if (rscriptType.test(node.type || "") && !jQuery._data(node, "globalEval") && jQuery.contains(doc, node)) {
                                if (node.src) {
                                    jQuery._evalUrl(node.src)
                                } else {
                                    jQuery.globalEval((node.text || node.textContent || node.innerHTML || "").replace(rcleanScript, ""))
                                }
                            }
                        }
                    }
                    fragment = first = null
                }
            }
            return this
        }
    });
    function manipulationTarget(elem, content) {
        return jQuery.nodeName(elem, "table") && jQuery.nodeName(content.nodeType === 1 ? content: content.firstChild, "tr") ? elem.getElementsByTagName("tbody")[0] || elem.appendChild(elem.ownerDocument.createElement("tbody")) : elem
    }
    function disableScript(elem) {
        elem.type = (jQuery.find.attr(elem, "type") !== null) + "/" + elem.type;
        return elem
    }
    function restoreScript(elem) {
        var match = rscriptTypeMasked.exec(elem.type);
        if (match) {
            elem.type = match[1]
        } else {
            elem.removeAttribute("type")
        }
        return elem
    }
    function setGlobalEval(elems, refElements) {
        var elem, i = 0;
        for (; (elem = elems[i]) != null; i++) {
            jQuery._data(elem, "globalEval", !refElements || jQuery._data(refElements[i], "globalEval"))
        }
    }
    function cloneCopyEvent(src, dest) {
        if (dest.nodeType !== 1 || !jQuery.hasData(src)) {
            return
        }
        var type, i, l, oldData = jQuery._data(src),
        curData = jQuery._data(dest, oldData),
        events = oldData.events;
        if (events) {
            delete curData.handle;
            curData.events = {};
            for (type in events) {
                for (i = 0, l = events[type].length; i < l; i++) {
                    jQuery.event.add(dest, type, events[type][i])
                }
            }
        }
        if (curData.data) {
            curData.data = jQuery.extend({},
            curData.data)
        }
    }
    function fixCloneNodeIssues(src, dest) {
        var nodeName, e, data;
        if (dest.nodeType !== 1) {
            return
        }
        nodeName = dest.nodeName.toLowerCase();
        if (!jQuery.support.noCloneEvent && dest[jQuery.expando]) {
            data = jQuery._data(dest);
            for (e in data.events) {
                jQuery.removeEvent(dest, e, data.handle)
            }
            dest.removeAttribute(jQuery.expando)
        }
        if (nodeName === "script" && dest.text !== src.text) {
            disableScript(dest).text = src.text;
            restoreScript(dest)
        } else if (nodeName === "object") {
            if (dest.parentNode) {
                dest.outerHTML = src.outerHTML
            }
            if (jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML))) {
                dest.innerHTML = src.innerHTML
            }
        } else if (nodeName === "input" && manipulation_rcheckableType.test(src.type)) {
            dest.defaultChecked = dest.checked = src.checked;
            if (dest.value !== src.value) {
                dest.value = src.value
            }
        } else if (nodeName === "option") {
            dest.defaultSelected = dest.selected = src.defaultSelected
        } else if (nodeName === "input" || nodeName === "textarea") {
            dest.defaultValue = src.defaultValue
        }
    }
    jQuery.each({
        appendTo: "append",
        prependTo: "prepend",
        insertBefore: "before",
        insertAfter: "after",
        replaceAll: "replaceWith"
    },
    function(name, original) {
        jQuery.fn[name] = function(selector) {
            var elems, i = 0,
            ret = [],
            insert = jQuery(selector),
            last = insert.length - 1;
            for (; i <= last; i++) {
                elems = i === last ? this: this.clone(true);
                jQuery(insert[i])[original](elems);
                core_push.apply(ret, elems.get())
            }
            return this.pushStack(ret)
        }
    });
    function getAll(context, tag) {
        var elems, elem, i = 0,
        found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName(tag || "*") : typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll(tag || "*") : undefined;
        if (!found) {
            for (found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++) {
                if (!tag || jQuery.nodeName(elem, tag)) {
                    found.push(elem)
                } else {
                    jQuery.merge(found, getAll(elem, tag))
                }
            }
        }
        return tag === undefined || tag && jQuery.nodeName(context, tag) ? jQuery.merge([context], found) : found
    }
    function fixDefaultChecked(elem) {
        if (manipulation_rcheckableType.test(elem.type)) {
            elem.defaultChecked = elem.checked
        }
    }
    jQuery.extend({
        clone: function(elem, dataAndEvents, deepDataAndEvents) {
            var destElements, node, clone, i, srcElements, inPage = jQuery.contains(elem.ownerDocument, elem);
            if (jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test("<" + elem.nodeName + ">")) {
                clone = elem.cloneNode(true)
            } else {
                fragmentDiv.innerHTML = elem.outerHTML;
                fragmentDiv.removeChild(clone = fragmentDiv.firstChild)
            }
            if ((!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) {
                destElements = getAll(clone);
                srcElements = getAll(elem);
                for (i = 0; (node = srcElements[i]) != null; ++i) {
                    if (destElements[i]) {
                        fixCloneNodeIssues(node, destElements[i])
                    }
                }
            }
            if (dataAndEvents) {
                if (deepDataAndEvents) {
                    srcElements = srcElements || getAll(elem);
                    destElements = destElements || getAll(clone);
                    for (i = 0; (node = srcElements[i]) != null; i++) {
                        cloneCopyEvent(node, destElements[i])
                    }
                } else {
                    cloneCopyEvent(elem, clone)
                }
            }
            destElements = getAll(clone, "script");
            if (destElements.length > 0) {
                setGlobalEval(destElements, !inPage && getAll(elem, "script"))
            }
            destElements = srcElements = node = null;
            return clone
        },
        buildFragment: function(elems, context, scripts, selection) {
            var j, elem, contains, tmp, tag, tbody, wrap, l = elems.length,
            safe = createSafeFragment(context),
            nodes = [],
            i = 0;
            for (; i < l; i++) {
                elem = elems[i];
                if (elem || elem === 0) {
                    if (jQuery.type(elem) === "object") {
                        jQuery.merge(nodes, elem.nodeType ? [elem] : elem)
                    } else if (!rhtml.test(elem)) {
                        nodes.push(context.createTextNode(elem))
                    } else {
                        tmp = tmp || safe.appendChild(context.createElement("div"));
                        tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
                        wrap = wrapMap[tag] || wrapMap._default;
                        tmp.innerHTML = wrap[1] + elem.replace(rxhtmlTag, "<$1></$2>") + wrap[2];
                        j = wrap[0];
                        while (j--) {
                            tmp = tmp.lastChild
                        }
                        if (!jQuery.support.leadingWhitespace && rleadingWhitespace.test(elem)) {
                            nodes.push(context.createTextNode(rleadingWhitespace.exec(elem)[0]))
                        }
                        if (!jQuery.support.tbody) {
                            elem = tag === "table" && !rtbody.test(elem) ? tmp.firstChild: wrap[1] === "<table>" && !rtbody.test(elem) ? tmp: 0;
                            j = elem && elem.childNodes.length;
                            while (j--) {
                                if (jQuery.nodeName(tbody = elem.childNodes[j], "tbody") && !tbody.childNodes.length) {
                                    elem.removeChild(tbody)
                                }
                            }
                        }
                        jQuery.merge(nodes, tmp.childNodes);
                        tmp.textContent = "";
                        while (tmp.firstChild) {
                            tmp.removeChild(tmp.firstChild)
                        }
                        tmp = safe.lastChild
                    }
                }
            }
            if (tmp) {
                safe.removeChild(tmp)
            }
            if (!jQuery.support.appendChecked) {
                jQuery.grep(getAll(nodes, "input"), fixDefaultChecked)
            }
            i = 0;
            while (elem = nodes[i++]) {
                if (selection && jQuery.inArray(elem, selection) !== -1) {
                    continue
                }
                contains = jQuery.contains(elem.ownerDocument, elem);
                tmp = getAll(safe.appendChild(elem), "script");
                if (contains) {
                    setGlobalEval(tmp)
                }
                if (scripts) {
                    j = 0;
                    while (elem = tmp[j++]) {
                        if (rscriptType.test(elem.type || "")) {
                            scripts.push(elem)
                        }
                    }
                }
            }
            tmp = null;
            return safe
        },
        cleanData: function(elems, acceptData) {
            var elem, type, id, data, i = 0,
            internalKey = jQuery.expando,
            cache = jQuery.cache,
            deleteExpando = jQuery.support.deleteExpando,
            special = jQuery.event.special;
            for (; (elem = elems[i]) != null; i++) {
                if (acceptData || jQuery.acceptData(elem)) {
                    id = elem[internalKey];
                    data = id && cache[id];
                    if (data) {
                        if (data.events) {
                            for (type in data.events) {
                                if (special[type]) {
                                    jQuery.event.remove(elem, type)
                                } else {
                                    jQuery.removeEvent(elem, type, data.handle)
                                }
                            }
                        }
                        if (cache[id]) {
                            delete cache[id];
                            if (deleteExpando) {
                                delete elem[internalKey]
                            } else if (typeof elem.removeAttribute !== core_strundefined) {
                                elem.removeAttribute(internalKey)
                            } else {
                                elem[internalKey] = null
                            }
                            core_deletedIds.push(id)
                        }
                    }
                }
            }
        },
        _evalUrl: function(url) {
            return jQuery.ajax({
                url: url,
                type: "GET",
                dataType: "script",
                async: false,
                global: false,
                "throws": true
            })
        }
    });
    jQuery.fn.extend({
        wrapAll: function(html) {
            if (jQuery.isFunction(html)) {
                return this.each(function(i) {
                    jQuery(this).wrapAll(html.call(this, i))
                })
            }
            if (this[0]) {
                var wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
                if (this[0].parentNode) {
                    wrap.insertBefore(this[0])
                }
                wrap.map(function() {
                    var elem = this;
                    while (elem.firstChild && elem.firstChild.nodeType === 1) {
                        elem = elem.firstChild
                    }
                    return elem
                }).append(this)
            }
            return this
        },
        wrapInner: function(html) {
            if (jQuery.isFunction(html)) {
                return this.each(function(i) {
                    jQuery(this).wrapInner(html.call(this, i))
                })
            }
            return this.each(function() {
                var self = jQuery(this),
                contents = self.contents();
                if (contents.length) {
                    contents.wrapAll(html)
                } else {
                    self.append(html)
                }
            })
        },
        wrap: function(html) {
            var isFunction = jQuery.isFunction(html);
            return this.each(function(i) {
                jQuery(this).wrapAll(isFunction ? html.call(this, i) : html)
            })
        },
        unwrap: function() {
            return this.parent().each(function() {
                if (!jQuery.nodeName(this, "body")) {
                    jQuery(this).replaceWith(this.childNodes)
                }
            }).end()
        }
    });
    var iframe, getStyles, curCSS, ralpha = /alpha\([^)]*\)/i,
    ropacity = /opacity\s*=\s*([^)]*)/,
    rposition = /^(top|right|bottom|left)$/,
    rdisplayswap = /^(none|table(?!-c[ea]).+)/,
    rmargin = /^margin/,
    rnumsplit = new RegExp("^(" + core_pnum + ")(.*)$", "i"),
    rnumnonpx = new RegExp("^(" + core_pnum + ")(?!px)[a-z%]+$", "i"),
    rrelNum = new RegExp("^([+-])=(" + core_pnum + ")", "i"),
    elemdisplay = {
        BODY: "block"
    },
    cssShow = {
        position: "absolute",
        visibility: "hidden",
        display: "block"
    },
    cssNormalTransform = {
        letterSpacing: 0,
        fontWeight: 400
    },
    cssExpand = ["Top", "Right", "Bottom", "Left"],
    cssPrefixes = ["Webkit", "O", "Moz", "ms"];
    function vendorPropName(style, name) {
        if (name in style) {
            return name
        }
        var capName = name.charAt(0).toUpperCase() + name.slice(1),
        origName = name,
        i = cssPrefixes.length;
        while (i--) {
            name = cssPrefixes[i] + capName;
            if (name in style) {
                return name
            }
        }
        return origName
    }
    function isHidden(elem, el) {
        elem = el || elem;
        return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem)
    }
    function showHide(elements, show) {
        var display, elem, hidden, values = [],
        index = 0,
        length = elements.length;
        for (; index < length; index++) {
            elem = elements[index];
            if (!elem.style) {
                continue
            }
            values[index] = jQuery._data(elem, "olddisplay");
            display = elem.style.display;
            if (show) {
                if (!values[index] && display === "none") {
                    elem.style.display = ""
                }
                if (elem.style.display === "" && isHidden(elem)) {
                    values[index] = jQuery._data(elem, "olddisplay", css_defaultDisplay(elem.nodeName))
                }
            } else {
                if (!values[index]) {
                    hidden = isHidden(elem);
                    if (display && display !== "none" || !hidden) {
                        jQuery._data(elem, "olddisplay", hidden ? display: jQuery.css(elem, "display"))
                    }
                }
            }
        }
        for (index = 0; index < length; index++) {
            elem = elements[index];
            if (!elem.style) {
                continue
            }
            if (!show || elem.style.display === "none" || elem.style.display === "") {
                elem.style.display = show ? values[index] || "": "none"
            }
        }
        return elements
    }
    jQuery.fn.extend({
        css: function(name, value) {
            return jQuery.access(this,
            function(elem, name, value) {
                var len, styles, map = {},
                i = 0;
                if (jQuery.isArray(name)) {
                    styles = getStyles(elem);
                    len = name.length;
                    for (; i < len; i++) {
                        map[name[i]] = jQuery.css(elem, name[i], false, styles)
                    }
                    return map
                }
                return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name)
            },
            name, value, arguments.length > 1)
        },
        show: function() {
            return showHide(this, true)
        },
        hide: function() {
            return showHide(this)
        },
        toggle: function(state) {
            if (typeof state === "boolean") {
                return state ? this.show() : this.hide()
            }
            return this.each(function() {
                if (isHidden(this)) {
                    jQuery(this).show()
                } else {
                    jQuery(this).hide()
                }
            })
        }
    });
    jQuery.extend({
        cssHooks: {
            opacity: {
                get: function(elem, computed) {
                    if (computed) {
                        var ret = curCSS(elem, "opacity");
                        return ret === "" ? "1": ret
                    }
                }
            }
        },
        cssNumber: {
            columnCount: true,
            fillOpacity: true,
            fontWeight: true,
            lineHeight: true,
            opacity: true,
            order: true,
            orphans: true,
            widows: true,
            zIndex: true,
            zoom: true
        },
        cssProps: {
            "float": jQuery.support.cssFloat ? "cssFloat": "styleFloat"
        },
        style: function(elem, name, value, extra) {
            if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
                return
            }
            var ret, type, hooks, origName = jQuery.camelCase(name),
            style = elem.style;
            name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(style, origName));
            hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
            if (value !== undefined) {
                type = typeof value;
                if (type === "string" && (ret = rrelNum.exec(value))) {
                    value = (ret[1] + 1) * ret[2] + parseFloat(jQuery.css(elem, name));
                    type = "number"
                }
                if (value == null || type === "number" && isNaN(value)) {
                    return
                }
                if (type === "number" && !jQuery.cssNumber[origName]) {
                    value += "px"
                }
                if (!jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
                    style[name] = "inherit"
                }
                if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
                    try {
                        style[name] = value
                    } catch(e) {}
                }
            } else {
                if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
                    return ret
                }
                return style[name]
            }
        },
        css: function(elem, name, extra, styles) {
            var num, val, hooks, origName = jQuery.camelCase(name);
            name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(elem.style, origName));
            hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
            if (hooks && "get" in hooks) {
                val = hooks.get(elem, true, extra)
            }
            if (val === undefined) {
                val = curCSS(elem, name, styles)
            }
            if (val === "normal" && name in cssNormalTransform) {
                val = cssNormalTransform[name]
            }
            if (extra === "" || extra) {
                num = parseFloat(val);
                return extra === true || jQuery.isNumeric(num) ? num || 0 : val
            }
            return val
        }
    });
    if (window.getComputedStyle) {
        getStyles = function(elem) {
            return window.getComputedStyle(elem, null)
        };
        curCSS = function(elem, name, _computed) {
            var width, minWidth, maxWidth, computed = _computed || getStyles(elem),
            ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined,
            style = elem.style;
            if (computed) {
                if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
                    ret = jQuery.style(elem, name)
                }
                if (rnumnonpx.test(ret) && rmargin.test(name)) {
                    width = style.width;
                    minWidth = style.minWidth;
                    maxWidth = style.maxWidth;
                    style.minWidth = style.maxWidth = style.width = ret;
                    ret = computed.width;
                    style.width = width;
                    style.minWidth = minWidth;
                    style.maxWidth = maxWidth
                }
            }
            return ret
        }
    } else if (document.documentElement.currentStyle) {
        getStyles = function(elem) {
            return elem.currentStyle
        };
        curCSS = function(elem, name, _computed) {
            var left, rs, rsLeft, computed = _computed || getStyles(elem),
            ret = computed ? computed[name] : undefined,
            style = elem.style;
            if (ret == null && style && style[name]) {
                ret = style[name]
            }
            if (rnumnonpx.test(ret) && !rposition.test(name)) {
                left = style.left;
                rs = elem.runtimeStyle;
                rsLeft = rs && rs.left;
                if (rsLeft) {
                    rs.left = elem.currentStyle.left
                }
                style.left = name === "fontSize" ? "1em": ret;
                ret = style.pixelLeft + "px";
                style.left = left;
                if (rsLeft) {
                    rs.left = rsLeft
                }
            }
            return ret === "" ? "auto": ret
        }
    }
    function setPositiveNumber(elem, value, subtract) {
        var matches = rnumsplit.exec(value);
        return matches ? Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || "px") : value
    }
    function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
        var i = extra === (isBorderBox ? "border": "content") ? 4 : name === "width" ? 1 : 0,
        val = 0;
        for (; i < 4; i += 2) {
            if (extra === "margin") {
                val += jQuery.css(elem, extra + cssExpand[i], true, styles)
            }
            if (isBorderBox) {
                if (extra === "content") {
                    val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles)
                }
                if (extra !== "margin") {
                    val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles)
                }
            } else {
                val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
                if (extra !== "padding") {
                    val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles)
                }
            }
        }
        return val
    }
    function getWidthOrHeight(elem, name, extra) {
        var valueIsBorderBox = true,
        val = name === "width" ? elem.offsetWidth: elem.offsetHeight,
        styles = getStyles(elem),
        isBorderBox = jQuery.support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box";
        if (val <= 0 || val == null) {
            val = curCSS(elem, name, styles);
            if (val < 0 || val == null) {
                val = elem.style[name]
            }
            if (rnumnonpx.test(val)) {
                return val
            }
            valueIsBorderBox = isBorderBox && (jQuery.support.boxSizingReliable || val === elem.style[name]);
            val = parseFloat(val) || 0
        }
        return val + augmentWidthOrHeight(elem, name, extra || (isBorderBox ? "border": "content"), valueIsBorderBox, styles) + "px"
    }
    function css_defaultDisplay(nodeName) {
        var doc = document,
        display = elemdisplay[nodeName];
        if (!display) {
            display = actualDisplay(nodeName, doc);
            if (display === "none" || !display) {
                iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>").css("cssText", "display:block !important")).appendTo(doc.documentElement);
                doc = (iframe[0].contentWindow || iframe[0].contentDocument).document;
                doc.write("<!doctype html><html><body>");
                doc.close();
                display = actualDisplay(nodeName, doc);
                iframe.detach()
            }
            elemdisplay[nodeName] = display
        }
        return display
    }
    function actualDisplay(name, doc) {
        var elem = jQuery(doc.createElement(name)).appendTo(doc.body),
        display = jQuery.css(elem[0], "display");
        elem.remove();
        return display
    }
    jQuery.each(["height", "width"],
    function(i, name) {
        jQuery.cssHooks[name] = {
            get: function(elem, computed, extra) {
                if (computed) {
                    return elem.offsetWidth === 0 && rdisplayswap.test(jQuery.css(elem, "display")) ? jQuery.swap(elem, cssShow,
                    function() {
                        return getWidthOrHeight(elem, name, extra)
                    }) : getWidthOrHeight(elem, name, extra)
                }
            },
            set: function(elem, value, extra) {
                var styles = extra && getStyles(elem);
                return setPositiveNumber(elem, value, extra ? augmentWidthOrHeight(elem, name, extra, jQuery.support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box", styles) : 0)
            }
        }
    });
    if (!jQuery.support.opacity) {
        jQuery.cssHooks.opacity = {
            get: function(elem, computed) {
                return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter: elem.style.filter) || "") ? .01 * parseFloat(RegExp.$1) + "": computed ? "1": ""
            },
            set: function(elem, value) {
                var style = elem.style,
                currentStyle = elem.currentStyle,
                opacity = jQuery.isNumeric(value) ? "alpha(opacity=" + value * 100 + ")": "",
                filter = currentStyle && currentStyle.filter || style.filter || "";
                style.zoom = 1;
                if ((value >= 1 || value === "") && jQuery.trim(filter.replace(ralpha, "")) === "" && style.removeAttribute) {
                    style.removeAttribute("filter");
                    if (value === "" || currentStyle && !currentStyle.filter) {
                        return
                    }
                }
                style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : filter + " " + opacity
            }
        }
    }
    jQuery(function() {
        if (!jQuery.support.reliableMarginRight) {
            jQuery.cssHooks.marginRight = {
                get: function(elem, computed) {
                    if (computed) {
                        return jQuery.swap(elem, {
                            display: "inline-block"
                        },
                        curCSS, [elem, "marginRight"])
                    }
                }
            }
        }
        if (!jQuery.support.pixelPosition && jQuery.fn.position) {
            jQuery.each(["top", "left"],
            function(i, prop) {
                jQuery.cssHooks[prop] = {
                    get: function(elem, computed) {
                        if (computed) {
                            computed = curCSS(elem, prop);
                            return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px": computed
                        }
                    }
                }
            })
        }
    });
    if (jQuery.expr && jQuery.expr.filters) {
        jQuery.expr.filters.hidden = function(elem) {
            return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 || !jQuery.support.reliableHiddenOffsets && (elem.style && elem.style.display || jQuery.css(elem, "display")) === "none"
        };
        jQuery.expr.filters.visible = function(elem) {
            return ! jQuery.expr.filters.hidden(elem)
        }
    }
    jQuery.each({
        margin: "",
        padding: "",
        border: "Width"
    },
    function(prefix, suffix) {
        jQuery.cssHooks[prefix + suffix] = {
            expand: function(value) {
                var i = 0,
                expanded = {},
                parts = typeof value === "string" ? value.split(" ") : [value];
                for (; i < 4; i++) {
                    expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0]
                }
                return expanded
            }
        };
        if (!rmargin.test(prefix)) {
            jQuery.cssHooks[prefix + suffix].set = setPositiveNumber
        }
    });
    var r20 = /%20/g,
    rbracket = /\[\]$/,
    rCRLF = /\r?\n/g,
    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
    rsubmittable = /^(?:input|select|textarea|keygen)/i;
    jQuery.fn.extend({
        serialize: function() {
            return jQuery.param(this.serializeArray())
        },
        serializeArray: function() {
            return this.map(function() {
                var elements = jQuery.prop(this, "elements");
                return elements ? jQuery.makeArray(elements) : this
            }).filter(function() {
                var type = this.type;
                return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !manipulation_rcheckableType.test(type))
            }).map(function(i, elem) {
                var val = jQuery(this).val();
                return val == null ? null: jQuery.isArray(val) ? jQuery.map(val,
                function(val) {
                    return {
                        name: elem.name,
                        value: val.replace(rCRLF, "\r\n")
                    }
                }) : {
                    name: elem.name,
                    value: val.replace(rCRLF, "\r\n")
                }
            }).get()
        }
    });
    jQuery.param = function(a, traditional) {
        var prefix, s = [],
        add = function(key, value) {
            value = jQuery.isFunction(value) ? value() : value == null ? "": value;
            s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value)
        };
        if (traditional === undefined) {
            traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional
        }
        if (jQuery.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
            jQuery.each(a,
            function() {
                add(this.name, this.value)
            })
        } else {
            for (prefix in a) {
                buildParams(prefix, a[prefix], traditional, add)
            }
        }
        return s.join("&").replace(r20, "+")
    };
    function buildParams(prefix, obj, traditional, add) {
        var name;
        if (jQuery.isArray(obj)) {
            jQuery.each(obj,
            function(i, v) {
                if (traditional || rbracket.test(prefix)) {
                    add(prefix, v)
                } else {
                    buildParams(prefix + "[" + (typeof v === "object" ? i: "") + "]", v, traditional, add)
                }
            })
        } else if (!traditional && jQuery.type(obj) === "object") {
            for (name in obj) {
                buildParams(prefix + "[" + name + "]", obj[name], traditional, add)
            }
        } else {
            add(prefix, obj)
        }
    }
    jQuery.each(("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error contextmenu").split(" "),
    function(i, name) {
        jQuery.fn[name] = function(data, fn) {
            return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name)
        }
    });
    jQuery.fn.extend({
        hover: function(fnOver, fnOut) {
            return this.mouseenter(fnOver).mouseleave(fnOut || fnOver)
        },
        bind: function(types, data, fn) {
            return this.on(types, null, data, fn)
        },
        unbind: function(types, fn) {
            return this.off(types, null, fn)
        },
        delegate: function(selector, types, data, fn) {
            return this.on(types, selector, data, fn)
        },
        undelegate: function(selector, types, fn) {
            return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn)
        }
    });
    var ajaxLocParts, ajaxLocation, ajax_nonce = jQuery.now(),
    ajax_rquery = /\?/,
    rhash = /#.*$/,
    rts = /([?&])_=[^&]*/,
    rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm,
    rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
    rnoContent = /^(?:GET|HEAD)$/,
    rprotocol = /^\/\//,
    rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
    _load = jQuery.fn.load,
    prefilters = {},
    transports = {},
    allTypes = "*/".concat("*");
    try {
        ajaxLocation = location.href
    } catch(e) {
        ajaxLocation = document.createElement("a");
        ajaxLocation.href = "";
        ajaxLocation = ajaxLocation.href
    }
    ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];
    function addToPrefiltersOrTransports(structure) {
        return function(dataTypeExpression, func) {
            if (typeof dataTypeExpression !== "string") {
                func = dataTypeExpression;
                dataTypeExpression = "*"
            }
            var dataType, i = 0,
            dataTypes = dataTypeExpression.toLowerCase().match(core_rnotwhite) || [];
            if (jQuery.isFunction(func)) {
                while (dataType = dataTypes[i++]) {
                    if (dataType[0] === "+") {
                        dataType = dataType.slice(1) || "*"; (structure[dataType] = structure[dataType] || []).unshift(func)
                    } else { (structure[dataType] = structure[dataType] || []).push(func)
                    }
                }
            }
        }
    }
    function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
        var inspected = {},
        seekingTransport = structure === transports;
        function inspect(dataType) {
            var selected;
            inspected[dataType] = true;
            jQuery.each(structure[dataType] || [],
            function(_, prefilterOrFactory) {
                var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
                if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
                    options.dataTypes.unshift(dataTypeOrTransport);
                    inspect(dataTypeOrTransport);
                    return false
                } else if (seekingTransport) {
                    return ! (selected = dataTypeOrTransport)
                }
            });
            return selected
        }
        return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*")
    }
    function ajaxExtend(target, src) {
        var deep, key, flatOptions = jQuery.ajaxSettings.flatOptions || {};
        for (key in src) {
            if (src[key] !== undefined) { (flatOptions[key] ? target: deep || (deep = {}))[key] = src[key]
            }
        }
        if (deep) {
            jQuery.extend(true, target, deep)
        }
        return target
    }
    jQuery.fn.load = function(url, params, callback) {
        if (typeof url !== "string" && _load) {
            return _load.apply(this, arguments)
        }
        var selector, response, type, self = this,
        off = url.indexOf(" ");
        if (off >= 0) {
            selector = url.slice(off, url.length);
            url = url.slice(0, off)
        }
        if (jQuery.isFunction(params)) {
            callback = params;
            params = undefined
        } else if (params && typeof params === "object") {
            type = "POST"
        }
        if (self.length > 0) {
            jQuery.ajax({
                url: url,
                type: type,
                dataType: "html",
                data: params
            }).done(function(responseText) {
                response = arguments;
                self.html(selector ? jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) : responseText)
            }).complete(callback &&
            function(jqXHR, status) {
                self.each(callback, response || [jqXHR.responseText, status, jqXHR])
            })
        }
        return this
    };
    jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"],
    function(i, type) {
        jQuery.fn[type] = function(fn) {
            return this.on(type, fn)
        }
    });
    jQuery.extend({
        active: 0,
        lastModified: {},
        etag: {},
        ajaxSettings: {
            url: ajaxLocation,
            type: "GET",
            isLocal: rlocalProtocol.test(ajaxLocParts[1]),
            global: true,
            processData: true,
            async: true,
            contentType: "application/x-www-form-urlencoded; charset=UTF-8",
            accepts: {
                "*": allTypes,
                text: "text/plain",
                html: "text/html",
                xml: "application/xml, text/xml",
                json: "application/json, text/javascript"
            },
            contents: {
                xml: /xml/,
                html: /html/,
                json: /json/
            },
            responseFields: {
                xml: "responseXML",
                text: "responseText",
                json: "responseJSON"
            },
            converters: {
                "* text": String,
                "text html": true,
                "text json": jQuery.parseJSON,
                "text xml": jQuery.parseXML
            },
            flatOptions: {
                url: true,
                context: true
            }
        },
        ajaxSetup: function(target, settings) {
            return settings ? ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : ajaxExtend(jQuery.ajaxSettings, target)
        },
        ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
        ajaxTransport: addToPrefiltersOrTransports(transports),
        ajax: function(url, options) {
            if (typeof url === "object") {
                options = url;
                url = undefined
            }
            options = options || {};
            var parts, i, cacheURL, responseHeadersString, timeoutTimer, fireGlobals, transport, responseHeaders, s = jQuery.ajaxSetup({},
            options),
            callbackContext = s.context || s,
            globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event,
            deferred = jQuery.Deferred(),
            completeDeferred = jQuery.Callbacks("once memory"),
            statusCode = s.statusCode || {},
            requestHeaders = {},
            requestHeadersNames = {},
            state = 0,
            strAbort = "canceled",
            jqXHR = {
                readyState: 0,
                getResponseHeader: function(key) {
                    var match;
                    if (state === 2) {
                        if (!responseHeaders) {
                            responseHeaders = {};
                            while (match = rheaders.exec(responseHeadersString)) {
                                responseHeaders[match[1].toLowerCase()] = match[2]
                            }
                        }
                        match = responseHeaders[key.toLowerCase()]
                    }
                    return match == null ? null: match
                },
                getAllResponseHeaders: function() {
                    return state === 2 ? responseHeadersString: null
                },
                setRequestHeader: function(name, value) {
                    var lname = name.toLowerCase();
                    if (!state) {
                        name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
                        requestHeaders[name] = value
                    }
                    return this
                },
                overrideMimeType: function(type) {
                    if (!state) {
                        s.mimeType = type
                    }
                    return this
                },
                statusCode: function(map) {
                    var code;
                    if (map) {
                        if (state < 2) {
                            for (code in map) {
                                statusCode[code] = [statusCode[code], map[code]]
                            }
                        } else {
                            jqXHR.always(map[jqXHR.status])
                        }
                    }
                    return this
                },
                abort: function(statusText) {
                    var finalText = statusText || strAbort;
                    if (transport) {
                        transport.abort(finalText)
                    }
                    done(0, finalText);
                    return this
                }
            };
            deferred.promise(jqXHR).complete = completeDeferred.add;
            jqXHR.success = jqXHR.done;
            jqXHR.error = jqXHR.fail;
            s.url = ((url || s.url || ajaxLocation) + "").replace(rhash, "").replace(rprotocol, ajaxLocParts[1] + "//");
            s.type = options.method || options.type || s.method || s.type;
            s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(core_rnotwhite) || [""];
            if (s.crossDomain == null) {
                parts = rurl.exec(s.url.toLowerCase());
                s.crossDomain = !!(parts && (parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] || (parts[3] || (parts[1] === "http:" ? "80": "443")) !== (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80": "443"))))
            }
            if (s.data && s.processData && typeof s.data !== "string") {
                s.data = jQuery.param(s.data, s.traditional)
            }
            inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
            if (state === 2) {
                return jqXHR
            }
            fireGlobals = s.global;
            if (fireGlobals && jQuery.active++===0) {
                jQuery.event.trigger("ajaxStart")
            }
            s.type = s.type.toUpperCase();
            s.hasContent = !rnoContent.test(s.type);
            cacheURL = s.url;
            if (!s.hasContent) {
                if (s.data) {
                    cacheURL = s.url += (ajax_rquery.test(cacheURL) ? "&": "?") + s.data;
                    delete s.data
                }
                if (s.cache === false) {
                    s.url = rts.test(cacheURL) ? cacheURL.replace(rts, "$1_=" + ajax_nonce++) : cacheURL + (ajax_rquery.test(cacheURL) ? "&": "?") + "_=" + ajax_nonce++
                }
            }
            if (s.ifModified) {
                if (jQuery.lastModified[cacheURL]) {
                    jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL])
                }
                if (jQuery.etag[cacheURL]) {
                    jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL])
                }
            }
            if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
                jqXHR.setRequestHeader("Content-Type", s.contentType)
            }
            jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01": "") : s.accepts["*"]);
            for (i in s.headers) {
                jqXHR.setRequestHeader(i, s.headers[i])
            }
            if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {
                return jqXHR.abort()
            }
            strAbort = "abort";
            for (i in {
                success: 1,
                error: 1,
                complete: 1
            }) {
                jqXHR[i](s[i])
            }
            transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
            if (!transport) {
                done( - 1, "No Transport")
            } else {
                jqXHR.readyState = 1;
                if (fireGlobals) {
                    globalEventContext.trigger("ajaxSend", [jqXHR, s])
                }
                if (s.async && s.timeout > 0) {
                    timeoutTimer = setTimeout(function() {
                        jqXHR.abort("timeout")
                    },
                    s.timeout)
                }
                try {
                    state = 1;
                    transport.send(requestHeaders, done)
                } catch(e) {
                    if (state < 2) {
                        done( - 1, e)
                    } else {
                        throw e
                    }
                }
            }
            function done(status, nativeStatusText, responses, headers) {
                var isSuccess, success, error, response, modified, statusText = nativeStatusText;
                if (state === 2) {
                    return
                }
                state = 2;
                if (timeoutTimer) {
                    clearTimeout(timeoutTimer)
                }
                transport = undefined;
                responseHeadersString = headers || "";
                jqXHR.readyState = status > 0 ? 4 : 0;
                isSuccess = status >= 200 && status < 300 || status === 304;
                if (responses) {
                    response = ajaxHandleResponses(s, jqXHR, responses)
                }
                response = ajaxConvert(s, response, jqXHR, isSuccess);
                if (isSuccess) {
                    if (s.ifModified) {
                        modified = jqXHR.getResponseHeader("Last-Modified");
                        if (modified) {
                            jQuery.lastModified[cacheURL] = modified
                        }
                        modified = jqXHR.getResponseHeader("etag");
                        if (modified) {
                            jQuery.etag[cacheURL] = modified
                        }
                    }
                    if (status === 204 || s.type === "HEAD") {
                        statusText = "nocontent"
                    } else if (status === 304) {
                        statusText = "notmodified"
                    } else {
                        statusText = response.state;
                        success = response.data;
                        error = response.error;
                        isSuccess = !error
                    }
                } else {
                    error = statusText;
                    if (status || !statusText) {
                        statusText = "error";
                        if (status < 0) {
                            status = 0
                        }
                    }
                }
                jqXHR.status = status;
                jqXHR.statusText = (nativeStatusText || statusText) + "";
                if (isSuccess) {
                    deferred.resolveWith(callbackContext, [success, statusText, jqXHR])
                } else {
                    deferred.rejectWith(callbackContext, [jqXHR, statusText, error])
                }
                jqXHR.statusCode(statusCode);
                statusCode = undefined;
                if (fireGlobals) {
                    globalEventContext.trigger(isSuccess ? "ajaxSuccess": "ajaxError", [jqXHR, s, isSuccess ? success: error])
                }
                completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
                if (fireGlobals) {
                    globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
                    if (!--jQuery.active) {
                        jQuery.event.trigger("ajaxStop")
                    }
                }
            }
            return jqXHR
        },
        getJSON: function(url, data, callback) {
            return jQuery.get(url, data, callback, "json")
        },
        getScript: function(url, callback) {
            return jQuery.get(url, undefined, callback, "script")
        }
    });
    jQuery.each(["get", "post"],
    function(i, method) {
        jQuery[method] = function(url, data, callback, type) {
            if (jQuery.isFunction(data)) {
                type = type || callback;
                callback = data;
                data = undefined
            }
            return jQuery.ajax({
                url: url,
                type: method,
                dataType: type,
                data: data,
                success: callback
            })
        }
    });
    function ajaxHandleResponses(s, jqXHR, responses) {
        var firstDataType, ct, finalDataType, type, contents = s.contents,
        dataTypes = s.dataTypes;
        while (dataTypes[0] === "*") {
            dataTypes.shift();
            if (ct === undefined) {
                ct = s.mimeType || jqXHR.getResponseHeader("Content-Type")
            }
        }
        if (ct) {
            for (type in contents) {
                if (contents[type] && contents[type].test(ct)) {
                    dataTypes.unshift(type);
                    break
                }
            }
        }
        if (dataTypes[0] in responses) {
            finalDataType = dataTypes[0]
        } else {
            for (type in responses) {
                if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
                    finalDataType = type;
                    break
                }
                if (!firstDataType) {
                    firstDataType = type
                }
            }
            finalDataType = finalDataType || firstDataType
        }
        if (finalDataType) {
            if (finalDataType !== dataTypes[0]) {
                dataTypes.unshift(finalDataType)
            }
            return responses[finalDataType]
        }
    }
    function ajaxConvert(s, response, jqXHR, isSuccess) {
        var conv2, current, conv, tmp, prev, converters = {},
        dataTypes = s.dataTypes.slice();
        if (dataTypes[1]) {
            for (conv in s.converters) {
                converters[conv.toLowerCase()] = s.converters[conv]
            }
        }
        current = dataTypes.shift();
        while (current) {
            if (s.responseFields[current]) {
                jqXHR[s.responseFields[current]] = response
            }
            if (!prev && isSuccess && s.dataFilter) {
                response = s.dataFilter(response, s.dataType)
            }
            prev = current;
            current = dataTypes.shift();
            if (current) {
                if (current === "*") {
                    current = prev
                } else if (prev !== "*" && prev !== current) {
                    conv = converters[prev + " " + current] || converters["* " + current];
                    if (!conv) {
                        for (conv2 in converters) {
                            tmp = conv2.split(" ");
                            if (tmp[1] === current) {
                                conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];
                                if (conv) {
                                    if (conv === true) {
                                        conv = converters[conv2]
                                    } else if (converters[conv2] !== true) {
                                        current = tmp[0];
                                        dataTypes.unshift(tmp[1])
                                    }
                                    break
                                }
                            }
                        }
                    }
                    if (conv !== true) {
                        if (conv && s["throws"]) {
                            response = conv(response)
                        } else {
                            try {
                                response = conv(response)
                            } catch(e) {
                                return {
                                    state: "parsererror",
                                    error: conv ? e: "No conversion from " + prev + " to " + current
                                }
                            }
                        }
                    }
                }
            }
        }
        return {
            state: "success",
            data: response
        }
    }
    jQuery.ajaxSetup({
        accepts: {
            script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
        },
        contents: {
            script: /(?:java|ecma)script/
        },
        converters: {
            "text script": function(text) {
                jQuery.globalEval(text);
                return text
            }
        }
    });
    jQuery.ajaxPrefilter("script",
    function(s) {
        if (s.cache === undefined) {
            s.cache = false
        }
        if (s.crossDomain) {
            s.type = "GET";
            s.global = false
        }
    });
    jQuery.ajaxTransport("script",
    function(s) {
        if (s.crossDomain) {
            var script, head = document.head || jQuery("head")[0] || document.documentElement;
            return {
                send: function(_, callback) {
                    script = document.createElement("script");
                    script.async = true;
                    if (s.scriptCharset) {
                        script.charset = s.scriptCharset
                    }
                    script.src = s.url;
                    script.onload = script.onreadystatechange = function(_, isAbort) {
                        if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
                            script.onload = script.onreadystatechange = null;
                            if (script.parentNode) {
                                script.parentNode.removeChild(script)
                            }
                            script = null;
                            if (!isAbort) {
                                callback(200, "success")
                            }
                        }
                    };
                    head.insertBefore(script, head.firstChild)
                },
                abort: function() {
                    if (script) {
                        script.onload(undefined, true)
                    }
                }
            }
        }
    });
    var oldCallbacks = [],
    rjsonp = /(=)\?(?=&|$)|\?\?/;
    jQuery.ajaxSetup({
        jsonp: "callback",
        jsonpCallback: function() {
            var callback = oldCallbacks.pop() || jQuery.expando + "_" + ajax_nonce++;
            this[callback] = true;
            return callback
        }
    });
    jQuery.ajaxPrefilter("json jsonp",
    function(s, originalSettings, jqXHR) {
        var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url": typeof s.data === "string" && !(s.contentType || "").indexOf("application/x-www-form-urlencoded") && rjsonp.test(s.data) && "data");
        if (jsonProp || s.dataTypes[0] === "jsonp") {
            callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback;
            if (jsonProp) {
                s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName)
            } else if (s.jsonp !== false) {
                s.url += (ajax_rquery.test(s.url) ? "&": "?") + s.jsonp + "=" + callbackName
            }
            s.converters["script json"] = function() {
                if (!responseContainer) {
                    jQuery.error(callbackName + " was not called")
                }
                return responseContainer[0]
            };
            s.dataTypes[0] = "json";
            overwritten = window[callbackName];
            window[callbackName] = function() {
                responseContainer = arguments
            };
            jqXHR.always(function() {
                window[callbackName] = overwritten;
                if (s[callbackName]) {
                    s.jsonpCallback = originalSettings.jsonpCallback;
                    oldCallbacks.push(callbackName)
                }
                if (responseContainer && jQuery.isFunction(overwritten)) {
                    overwritten(responseContainer[0])
                }
                responseContainer = overwritten = undefined
            });
            return "script"
        }
    });
    var xhrCallbacks, xhrSupported, xhrId = 0,
    xhrOnUnloadAbort = window.ActiveXObject &&
    function() {
        var key;
        for (key in xhrCallbacks) {
            xhrCallbacks[key](undefined, true)
        }
    };
    function createStandardXHR() {
        try {
            return new window.XMLHttpRequest
        } catch(e) {}
    }
    function createActiveXHR() {
        try {
            return new window.ActiveXObject("Microsoft.XMLHTTP")
        } catch(e) {}
    }
    jQuery.ajaxSettings.xhr = window.ActiveXObject ?
    function() {
        return ! this.isLocal && createStandardXHR() || createActiveXHR()
    }: createStandardXHR;
    xhrSupported = jQuery.ajaxSettings.xhr();
    jQuery.support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
    xhrSupported = jQuery.support.ajax = !!xhrSupported;
    if (xhrSupported) {
        jQuery.ajaxTransport(function(s) {
            if (!s.crossDomain || jQuery.support.cors) {
                var callback;
                return {
                    send: function(headers, complete) {
                        var handle, i, xhr = s.xhr();
                        if (s.username) {
                            xhr.open(s.type, s.url, s.async, s.username, s.password)
                        } else {
                            xhr.open(s.type, s.url, s.async)
                        }
                        if (s.xhrFields) {
                            for (i in s.xhrFields) {
                                xhr[i] = s.xhrFields[i]
                            }
                        }
                        if (s.mimeType && xhr.overrideMimeType) {
                            xhr.overrideMimeType(s.mimeType)
                        }
                        if (!s.crossDomain && !headers["X-Requested-With"]) {
                            headers["X-Requested-With"] = "XMLHttpRequest"
                        }
                        try {
                            for (i in headers) {
                                xhr.setRequestHeader(i, headers[i])
                            }
                        } catch(err) {}
                        xhr.send(s.hasContent && s.data || null);
                        callback = function(_, isAbort) {
                            var status, responseHeaders, statusText, responses;
                            try {
                                if (callback && (isAbort || xhr.readyState === 4)) {
                                    callback = undefined;
                                    if (handle) {
                                        xhr.onreadystatechange = jQuery.noop;
                                        if (xhrOnUnloadAbort) {
                                            delete xhrCallbacks[handle]
                                        }
                                    }
                                    if (isAbort) {
                                        if (xhr.readyState !== 4) {
                                            xhr.abort()
                                        }
                                    } else {
                                        responses = {};
                                        status = xhr.status;
                                        responseHeaders = xhr.getAllResponseHeaders();
                                        if (typeof xhr.responseText === "string") {
                                            responses.text = xhr.responseText
                                        }
                                        try {
                                            statusText = xhr.statusText
                                        } catch(e) {
                                            statusText = ""
                                        }
                                        if (!status && s.isLocal && !s.crossDomain) {
                                            status = responses.text ? 200 : 404
                                        } else if (status === 1223) {
                                            status = 204
                                        }
                                    }
                                }
                            } catch(firefoxAccessException) {
                                if (!isAbort) {
                                    complete( - 1, firefoxAccessException)
                                }
                            }
                            if (responses) {
                                complete(status, statusText, responses, responseHeaders)
                            }
                        };
                        if (!s.async) {
                            callback()
                        } else if (xhr.readyState === 4) {
                            setTimeout(callback)
                        } else {
                            handle = ++xhrId;
                            if (xhrOnUnloadAbort) {
                                if (!xhrCallbacks) {
                                    xhrCallbacks = {};
                                    jQuery(window).unload(xhrOnUnloadAbort)
                                }
                                xhrCallbacks[handle] = callback
                            }
                            xhr.onreadystatechange = callback
                        }
                    },
                    abort: function() {
                        if (callback) {
                            callback(undefined, true)
                        }
                    }
                }
            }
        })
    }
    var fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/,
    rfxnum = new RegExp("^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i"),
    rrun = /queueHooks$/,
    animationPrefilters = [defaultPrefilter],
    tweeners = {
        "*": [function(prop, value) {
            var tween = this.createTween(prop, value),
            target = tween.cur(),
            parts = rfxnum.exec(value),
            unit = parts && parts[3] || (jQuery.cssNumber[prop] ? "": "px"),
            start = (jQuery.cssNumber[prop] || unit !== "px" && +target) && rfxnum.exec(jQuery.css(tween.elem, prop)),
            scale = 1,
            maxIterations = 20;
            if (start && start[3] !== unit) {
                unit = unit || start[3];
                parts = parts || [];
                start = +target || 1;
                do {
                    scale = scale || ".5";
                    start = start / scale;
                    jQuery.style(tween.elem, prop, start + unit)
                } while ( scale !== ( scale = tween . cur () / target) && scale !== 1 && --maxIterations)
            }
            if (parts) {
                start = tween.start = +start || +target || 0;
                tween.unit = unit;
                tween.end = parts[1] ? start + (parts[1] + 1) * parts[2] : +parts[2]
            }
            return tween
        }]
    };
    function createFxNow() {
        setTimeout(function() {
            fxNow = undefined
        });
        return fxNow = jQuery.now()
    }
    function createTween(value, prop, animation) {
        var tween, collection = (tweeners[prop] || []).concat(tweeners["*"]),
        index = 0,
        length = collection.length;
        for (; index < length; index++) {
            if (tween = collection[index].call(animation, prop, value)) {
                return tween
            }
        }
    }
    function Animation(elem, properties, options) {
        var result, stopped, index = 0,
        length = animationPrefilters.length,
        deferred = jQuery.Deferred().always(function() {
            delete tick.elem
        }),
        tick = function() {
            if (stopped) {
                return false
            }
            var currentTime = fxNow || createFxNow(),
            remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
            temp = remaining / animation.duration || 0,
            percent = 1 - temp,
            index = 0,
            length = animation.tweens.length;
            for (; index < length; index++) {
                animation.tweens[index].run(percent)
            }
            deferred.notifyWith(elem, [animation, percent, remaining]);
            if (percent < 1 && length) {
                return remaining
            } else {
                deferred.resolveWith(elem, [animation]);
                return false
            }
        },
        animation = deferred.promise({
            elem: elem,
            props: jQuery.extend({},
            properties),
            opts: jQuery.extend(true, {
                specialEasing: {}
            },
            options),
            originalProperties: properties,
            originalOptions: options,
            startTime: fxNow || createFxNow(),
            duration: options.duration,
            tweens: [],
            createTween: function(prop, end) {
                var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing);
                animation.tweens.push(tween);
                return tween
            },
            stop: function(gotoEnd) {
                var index = 0,
                length = gotoEnd ? animation.tweens.length: 0;
                if (stopped) {
                    return this
                }
                stopped = true;
                for (; index < length; index++) {
                    animation.tweens[index].run(1)
                }
                if (gotoEnd) {
                    deferred.resolveWith(elem, [animation, gotoEnd])
                } else {
                    deferred.rejectWith(elem, [animation, gotoEnd])
                }
                return this
            }
        }),
        props = animation.props;
        propFilter(props, animation.opts.specialEasing);
        for (; index < length; index++) {
            result = animationPrefilters[index].call(animation, elem, props, animation.opts);
            if (result) {
                return result
            }
        }
        jQuery.map(props, createTween, animation);
        if (jQuery.isFunction(animation.opts.start)) {
            animation.opts.start.call(elem, animation)
        }
        jQuery.fx.timer(jQuery.extend(tick, {
            elem: elem,
            anim: animation,
            queue: animation.opts.queue
        }));
        return animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always)
    }
    function propFilter(props, specialEasing) {
        var index, name, easing, value, hooks;
        for (index in props) {
            name = jQuery.camelCase(index);
            easing = specialEasing[name];
            value = props[index];
            if (jQuery.isArray(value)) {
                easing = value[1];
                value = props[index] = value[0]
            }
            if (index !== name) {
                props[name] = value;
                delete props[index]
            }
            hooks = jQuery.cssHooks[name];
            if (hooks && "expand" in hooks) {
                value = hooks.expand(value);
                delete props[name];
                for (index in value) {
                    if (! (index in props)) {
                        props[index] = value[index];
                        specialEasing[index] = easing
                    }
                }
            } else {
                specialEasing[name] = easing
            }
        }
    }
    jQuery.Animation = jQuery.extend(Animation, {
        tweener: function(props, callback) {
            if (jQuery.isFunction(props)) {
                callback = props;
                props = ["*"]
            } else {
                props = props.split(" ")
            }
            var prop, index = 0,
            length = props.length;
            for (; index < length; index++) {
                prop = props[index];
                tweeners[prop] = tweeners[prop] || [];
                tweeners[prop].unshift(callback)
            }
        },
        prefilter: function(callback, prepend) {
            if (prepend) {
                animationPrefilters.unshift(callback)
            } else {
                animationPrefilters.push(callback)
            }
        }
    });
    function defaultPrefilter(elem, props, opts) {
        var prop, value, toggle, tween, hooks, oldfire, anim = this,
        orig = {},
        style = elem.style,
        hidden = elem.nodeType && isHidden(elem),
        dataShow = jQuery._data(elem, "fxshow");
        if (!opts.queue) {
            hooks = jQuery._queueHooks(elem, "fx");
            if (hooks.unqueued == null) {
                hooks.unqueued = 0;
                oldfire = hooks.empty.fire;
                hooks.empty.fire = function() {
                    if (!hooks.unqueued) {
                        oldfire()
                    }
                }
            }
            hooks.unqueued++;
            anim.always(function() {
                anim.always(function() {
                    hooks.unqueued--;
                    if (!jQuery.queue(elem, "fx").length) {
                        hooks.empty.fire()
                    }
                })
            })
        }
        if (elem.nodeType === 1 && ("height" in props || "width" in props)) {
            opts.overflow = [style.overflow, style.overflowX, style.overflowY];
            if (jQuery.css(elem, "display") === "inline" && jQuery.css(elem, "float") === "none") {
                if (!jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay(elem.nodeName) === "inline") {
                    style.display = "inline-block"
                } else {
                    style.zoom = 1
                }
            }
        }
        if (opts.overflow) {
            style.overflow = "hidden";
            if (!jQuery.support.shrinkWrapBlocks) {
                anim.always(function() {
                    style.overflow = opts.overflow[0];
                    style.overflowX = opts.overflow[1];
                    style.overflowY = opts.overflow[2]
                })
            }
        }
        for (prop in props) {
            value = props[prop];
            if (rfxtypes.exec(value)) {
                delete props[prop];
                toggle = toggle || value === "toggle";
                if (value === (hidden ? "hide": "show")) {
                    continue
                }
                orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop)
            }
        }
        if (!jQuery.isEmptyObject(orig)) {
            if (dataShow) {
                if ("hidden" in dataShow) {
                    hidden = dataShow.hidden
                }
            } else {
                dataShow = jQuery._data(elem, "fxshow", {})
            }
            if (toggle) {
                dataShow.hidden = !hidden
            }
            if (hidden) {
                jQuery(elem).show()
            } else {
                anim.done(function() {
                    jQuery(elem).hide()
                })
            }
            anim.done(function() {
                var prop;
                jQuery._removeData(elem, "fxshow");
                for (prop in orig) {
                    jQuery.style(elem, prop, orig[prop])
                }
            });
            for (prop in orig) {
                tween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
                if (! (prop in dataShow)) {
                    dataShow[prop] = tween.start;
                    if (hidden) {
                        tween.end = tween.start;
                        tween.start = prop === "width" || prop === "height" ? 1 : 0
                    }
                }
            }
        }
    }
    function Tween(elem, options, prop, end, easing) {
        return new Tween.prototype.init(elem, options, prop, end, easing)
    }
    jQuery.Tween = Tween;
    Tween.prototype = {
        constructor: Tween,
        init: function(elem, options, prop, end, easing, unit) {
            this.elem = elem;
            this.prop = prop;
            this.easing = easing || "swing";
            this.options = options;
            this.start = this.now = this.cur();
            this.end = end;
            this.unit = unit || (jQuery.cssNumber[prop] ? "": "px")
        },
        cur: function() {
            var hooks = Tween.propHooks[this.prop];
            return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this)
        },
        run: function(percent) {
            var eased, hooks = Tween.propHooks[this.prop];
            if (this.options.duration) {
                this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration)
            } else {
                this.pos = eased = percent
            }
            this.now = (this.end - this.start) * eased + this.start;
            if (this.options.step) {
                this.options.step.call(this.elem, this.now, this)
            }
            if (hooks && hooks.set) {
                hooks.set(this)
            } else {
                Tween.propHooks._default.set(this)
            }
            return this
        }
    };
    Tween.prototype.init.prototype = Tween.prototype;
    Tween.propHooks = {
        _default: {
            get: function(tween) {
                var result;
                if (tween.elem[tween.prop] != null && (!tween.elem.style || tween.elem.style[tween.prop] == null)) {
                    return tween.elem[tween.prop]
                }
                result = jQuery.css(tween.elem, tween.prop, "");
                return ! result || result === "auto" ? 0 : result
            },
            set: function(tween) {
                if (jQuery.fx.step[tween.prop]) {
                    jQuery.fx.step[tween.prop](tween)
                } else if (tween.elem.style && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
                    jQuery.style(tween.elem, tween.prop, tween.now + tween.unit)
                } else {
                    tween.elem[tween.prop] = tween.now
                }
            }
        }
    };
    Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
        set: function(tween) {
            if (tween.elem.nodeType && tween.elem.parentNode) {
                tween.elem[tween.prop] = tween.now
            }
        }
    };
    jQuery.each(["toggle", "show", "hide"],
    function(i, name) {
        var cssFn = jQuery.fn[name];
        jQuery.fn[name] = function(speed, easing, callback) {
            return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback)
        }
    });
    jQuery.fn.extend({
        fadeTo: function(speed, to, easing, callback) {
            return this.filter(isHidden).css("opacity", 0).show().end().animate({
                opacity: to
            },
            speed, easing, callback)
        },
        animate: function(prop, speed, easing, callback) {
            var empty = jQuery.isEmptyObject(prop),
            optall = jQuery.speed(speed, easing, callback),
            doAnimation = function() {
                var anim = Animation(this, jQuery.extend({},
                prop), optall);
                if (empty || jQuery._data(this, "finish")) {
                    anim.stop(true)
                }
            };
            doAnimation.finish = doAnimation;
            return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation)
        },
        stop: function(type, clearQueue, gotoEnd) {
            var stopQueue = function(hooks) {
                var stop = hooks.stop;
                delete hooks.stop;
                stop(gotoEnd)
            };
            if (typeof type !== "string") {
                gotoEnd = clearQueue;
                clearQueue = type;
                type = undefined
            }
            if (clearQueue && type !== false) {
                this.queue(type || "fx", [])
            }
            return this.each(function() {
                var dequeue = true,
                index = type != null && type + "queueHooks",
                timers = jQuery.timers,
                data = jQuery._data(this);
                if (index) {
                    if (data[index] && data[index].stop) {
                        stopQueue(data[index])
                    }
                } else {
                    for (index in data) {
                        if (data[index] && data[index].stop && rrun.test(index)) {
                            stopQueue(data[index])
                        }
                    }
                }
                for (index = timers.length; index--;) {
                    if (timers[index].elem === this && (type == null || timers[index].queue === type)) {
                        timers[index].anim.stop(gotoEnd);
                        dequeue = false;
                        timers.splice(index, 1)
                    }
                }
                if (dequeue || !gotoEnd) {
                    jQuery.dequeue(this, type)
                }
            })
        },
        finish: function(type) {
            if (type !== false) {
                type = type || "fx"
            }
            return this.each(function() {
                var index, data = jQuery._data(this),
                queue = data[type + "queue"],
                hooks = data[type + "queueHooks"],
                timers = jQuery.timers,
                length = queue ? queue.length: 0;
                data.finish = true;
                jQuery.queue(this, type, []);
                if (hooks && hooks.stop) {
                    hooks.stop.call(this, true)
                }
                for (index = timers.length; index--;) {
                    if (timers[index].elem === this && timers[index].queue === type) {
                        timers[index].anim.stop(true);
                        timers.splice(index, 1)
                    }
                }
                for (index = 0; index < length; index++) {
                    if (queue[index] && queue[index].finish) {
                        queue[index].finish.call(this)
                    }
                }
                delete data.finish
            })
        }
    });
    function genFx(type, includeWidth) {
        var which, attrs = {
            height: type
        },
        i = 0;
        includeWidth = includeWidth ? 1 : 0;
        for (; i < 4; i += 2 - includeWidth) {
            which = cssExpand[i];
            attrs["margin" + which] = attrs["padding" + which] = type
        }
        if (includeWidth) {
            attrs.opacity = attrs.width = type
        }
        return attrs
    }
    jQuery.each({
        slideDown: genFx("show"),
        slideUp: genFx("hide"),
        slideToggle: genFx("toggle"),
        fadeIn: {
            opacity: "show"
        },
        fadeOut: {
            opacity: "hide"
        },
        fadeToggle: {
            opacity: "toggle"
        }
    },
    function(name, props) {
        jQuery.fn[name] = function(speed, easing, callback) {
            return this.animate(props, speed, easing, callback)
        }
    });
    jQuery.speed = function(speed, easing, fn) {
        var opt = speed && typeof speed === "object" ? jQuery.extend({},
        speed) : {
            complete: fn || !fn && easing || jQuery.isFunction(speed) && speed,
            duration: speed,
            easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
        };
        opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration: opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
        if (opt.queue == null || opt.queue === true) {
            opt.queue = "fx"
        }
        opt.old = opt.complete;
        opt.complete = function() {
            if (jQuery.isFunction(opt.old)) {
                opt.old.call(this)
            }
            if (opt.queue) {
                jQuery.dequeue(this, opt.queue)
            }
        };
        return opt
    };
    jQuery.easing = {
        linear: function(p) {
            return p
        },
        swing: function(p) {
            return.5 - Math.cos(p * Math.PI) / 2
        }
    };
    jQuery.timers = [];
    jQuery.fx = Tween.prototype.init;
    jQuery.fx.tick = function() {
        var timer, timers = jQuery.timers,
        i = 0;
        fxNow = jQuery.now();
        for (; i < timers.length; i++) {
            timer = timers[i];
            if (!timer() && timers[i] === timer) {
                timers.splice(i--, 1)
            }
        }
        if (!timers.length) {
            jQuery.fx.stop()
        }
        fxNow = undefined
    };
    jQuery.fx.timer = function(timer) {
        if (timer() && jQuery.timers.push(timer)) {
            jQuery.fx.start()
        }
    };
    jQuery.fx.interval = 13;
    jQuery.fx.start = function() {
        if (!timerId) {
            timerId = setInterval(jQuery.fx.tick, jQuery.fx.interval)
        }
    };
    jQuery.fx.stop = function() {
        clearInterval(timerId);
        timerId = null
    };
    jQuery.fx.speeds = {
        slow: 600,
        fast: 200,
        _default: 400
    };
    jQuery.fx.step = {};
    if (jQuery.expr && jQuery.expr.filters) {
        jQuery.expr.filters.animated = function(elem) {
            return jQuery.grep(jQuery.timers,
            function(fn) {
                return elem === fn.elem
            }).length
        }
    }
    jQuery.fn.offset = function(options) {
        if (arguments.length) {
            return options === undefined ? this: this.each(function(i) {
                jQuery.offset.setOffset(this, options, i)
            })
        }
        var docElem, win, box = {
            top: 0,
            left: 0
        },
        elem = this[0],
        doc = elem && elem.ownerDocument;
        if (!doc) {
            return
        }
        docElem = doc.documentElement;
        if (!jQuery.contains(docElem, elem)) {
            return box
        }
        if (typeof elem.getBoundingClientRect !== core_strundefined) {
            box = elem.getBoundingClientRect()
        }
        win = getWindow(doc);
        return {
            top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
            left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
        }
    };
    jQuery.offset = {
        setOffset: function(elem, options, i) {
            var position = jQuery.css(elem, "position");
            if (position === "static") {
                elem.style.position = "relative"
            }
            var curElem = jQuery(elem),
            curOffset = curElem.offset(),
            curCSSTop = jQuery.css(elem, "top"),
            curCSSLeft = jQuery.css(elem, "left"),
            calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
            props = {},
            curPosition = {},
            curTop,
            curLeft;
            if (calculatePosition) {
                curPosition = curElem.position();
                curTop = curPosition.top;
                curLeft = curPosition.left
            } else {
                curTop = parseFloat(curCSSTop) || 0;
                curLeft = parseFloat(curCSSLeft) || 0
            }
            if (jQuery.isFunction(options)) {
                options = options.call(elem, i, curOffset)
            }
            if (options.top != null) {
                props.top = options.top - curOffset.top + curTop
            }
            if (options.left != null) {
                props.left = options.left - curOffset.left + curLeft
            }
            if ("using" in options) {
                options.using.call(elem, props)
            } else {
                curElem.css(props)
            }
        }
    };
    jQuery.fn.extend({
        position: function() {
            if (!this[0]) {
                return
            }
            var offsetParent, offset, parentOffset = {
                top: 0,
                left: 0
            },
            elem = this[0];
            if (jQuery.css(elem, "position") === "fixed") {
                offset = elem.getBoundingClientRect()
            } else {
                offsetParent = this.offsetParent();
                offset = this.offset();
                if (!jQuery.nodeName(offsetParent[0], "html")) {
                    parentOffset = offsetParent.offset()
                }
                parentOffset.top += jQuery.css(offsetParent[0], "borderTopWidth", true);
                parentOffset.left += jQuery.css(offsetParent[0], "borderLeftWidth", true)
            }
            return {
                top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
                left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
            }
        },
        offsetParent: function() {
            return this.map(function() {
                var offsetParent = this.offsetParent || docElem;
                while (offsetParent && (!jQuery.nodeName(offsetParent, "html") && jQuery.css(offsetParent, "position") === "static")) {
                    offsetParent = offsetParent.offsetParent
                }
                return offsetParent || docElem
            })
        }
    });
    jQuery.each({
        scrollLeft: "pageXOffset",
        scrollTop: "pageYOffset"
    },
    function(method, prop) {
        var top = /Y/.test(prop);
        jQuery.fn[method] = function(val) {
            return jQuery.access(this,
            function(elem, method, val) {
                var win = getWindow(elem);
                if (val === undefined) {
                    return win ? prop in win ? win[prop] : win.document.documentElement[method] : elem[method]
                }
                if (win) {
                    win.scrollTo(!top ? val: jQuery(win).scrollLeft(), top ? val: jQuery(win).scrollTop())
                } else {
                    elem[method] = val
                }
            },
            method, val, arguments.length, null)
        }
    });
    function getWindow(elem) {
        return jQuery.isWindow(elem) ? elem: elem.nodeType === 9 ? elem.defaultView || elem.parentWindow: false
    }
    jQuery.each({
        Height: "height",
        Width: "width"
    },
    function(name, type) {
        jQuery.each({
            padding: "inner" + name,
            content: type,
            "": "outer" + name
        },
        function(defaultExtra, funcName) {
            jQuery.fn[funcName] = function(margin, value) {
                var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
                extra = defaultExtra || (margin === true || value === true ? "margin": "border");
                return jQuery.access(this,
                function(elem, type, value) {
                    var doc;
                    if (jQuery.isWindow(elem)) {
                        return elem.document.documentElement["client" + name]
                    }
                    if (elem.nodeType === 9) {
                        doc = elem.documentElement;
                        return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name])
                    }
                    return value === undefined ? jQuery.css(elem, type, extra) : jQuery.style(elem, type, value, extra)
                },
                type, chainable ? margin: undefined, chainable, null)
            }
        })
    });
    jQuery.fn.size = function() {
        return this.length
    };
    jQuery.fn.andSelf = jQuery.fn.addBack;
    if (typeof module === "object" && module && typeof module.exports === "object") {
        module.exports = jQuery
    } else {
        window.jQuery = window.$ = jQuery;
        if (typeof define === "function" && define.amd) {
            define("jquery", [],
            function() {
                return jQuery
            })
        }
    }
})(window); (function($) {
    function getPasteEvent() {
        var el = document.createElement("input"),
        name = "onpaste";
        el.setAttribute(name, "");
        return typeof el[name] === "function" ? "paste": "input"
    }
    var pasteEventName = getPasteEvent() + ".mask",
    ua = navigator.userAgent,
    iPhone = /iphone/i.test(ua),
    android = /android/i.test(ua),
    caretTimeoutId;
    $.mask = {
        definitions: {
            9 : "[0-9]",
            a: "[A-Za-z]",
            "*": "[A-Za-z0-9]"
        },
        dataName: "rawMaskFn",
        placeholder: "_"
    };
    $.fn.extend({
        caret: function(begin, end) {
            var range;
            if (this.length === 0 || this.is(":hidden")) {
                return
            }
            if (typeof begin == "number") {
                end = typeof end === "number" ? end: begin;
                return this.each(function() {
                    if (this.setSelectionRange) {
                        this.setSelectionRange(begin, end)
                    } else if (this.createTextRange) {
                        range = this.createTextRange();
                        range.collapse(true);
                        range.moveEnd("character", end);
                        range.moveStart("character", begin);
                        range.select()
                    }
                })
            } else {
                if (this[0].setSelectionRange) {
                    begin = this[0].selectionStart;
                    end = this[0].selectionEnd
                } else if (document.selection && document.selection.createRange) {
                    range = document.selection.createRange();
                    begin = 0 - range.duplicate().moveStart("character", -1e5);
                    end = begin + range.text.length
                }
                return {
                    begin: begin,
                    end: end
                }
            }
        },
        unmask: function() {
            return this.trigger("unmask")
        },
        mask: function(mask, settings) {
            var input, defs, tests, partialPosition, firstNonMaskPos, len;
            if (!mask && this.length > 0) {
                input = $(this[0]);
                return input.data($.mask.dataName)()
            }
            settings = $.extend({
                placeholder: $.mask.placeholder,
                completed: null
            },
            settings);
            defs = $.mask.definitions;
            tests = [];
            partialPosition = len = mask.length;
            firstNonMaskPos = null;
            $.each(mask.split(""),
            function(i, c) {
                if (c == "?") {
                    len--;
                    partialPosition = i
                } else if (defs[c]) {
                    tests.push(new RegExp(defs[c]));
                    if (firstNonMaskPos === null) {
                        firstNonMaskPos = tests.length - 1
                    }
                } else {
                    tests.push(null)
                }
            });
            return this.trigger("unmask").each(function() {
                var input = $(this),
                buffer = $.map(mask.split(""),
                function(c, i) {
                    if (c != "?") {
                        return defs[c] ? settings.placeholder: c
                    }
                }),
                focusText = input.val();
                function seekNext(pos) {
                    while (++pos < len && !tests[pos]);
                    return pos
                }
                function seekPrev(pos) {
                    while (--pos >= 0 && !tests[pos]);
                    return pos
                }
                function shiftL(begin, end) {
                    var i, j;
                    if (begin < 0) {
                        return
                    }
                    for (i = begin, j = seekNext(end); i < len; i++) {
                        if (tests[i]) {
                            if (j < len && tests[i].test(buffer[j])) {
                                buffer[i] = buffer[j];
                                buffer[j] = settings.placeholder
                            } else {
                                break
                            }
                            j = seekNext(j)
                        }
                    }
                    writeBuffer();
                    input.caret(Math.max(firstNonMaskPos, begin))
                }
                function shiftR(pos) {
                    var i, c, j, t;
                    for (i = pos, c = settings.placeholder; i < len; i++) {
                        if (tests[i]) {
                            j = seekNext(i);
                            t = buffer[i];
                            buffer[i] = c;
                            if (j < len && tests[j].test(t)) {
                                c = t
                            } else {
                                break
                            }
                        }
                    }
                }
                function keydownEvent(e) {
                    var k = e.which,
                    pos, begin, end;
                    if (k === 8 || k === 46 || iPhone && k === 127) {
                        pos = input.caret();
                        begin = pos.begin;
                        end = pos.end;
                        if (end - begin === 0) {
                            begin = k !== 46 ? seekPrev(begin) : end = seekNext(begin - 1);
                            end = k === 46 ? seekNext(end) : end
                        }
                        clearBuffer(begin, end);
                        shiftL(begin, end - 1);
                        e.preventDefault()
                    } else if (k == 27) {
                        input.val(focusText);
                        input.caret(0, checkVal());
                        e.preventDefault()
                    }
                }
                function keypressEvent(e) {
                    var k = e.which,
                    pos = input.caret(),
                    p,
                    c,
                    next;
                    if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {
                        return
                    } else if (k) {
                        if (pos.end - pos.begin !== 0) {
                            clearBuffer(pos.begin, pos.end);
                            shiftL(pos.begin, pos.end - 1)
                        }
                        p = seekNext(pos.begin - 1);
                        if (p < len) {
                            c = String.fromCharCode(k);
                            if (tests[p].test(c)) {
                                shiftR(p);
                                buffer[p] = c;
                                writeBuffer();
                                next = seekNext(p);
                                if (android) {
                                    setTimeout($.proxy($.fn.caret, input, next), 0)
                                } else {
                                    input.caret(next)
                                }
                                if (settings.completed && next >= len) {
                                    settings.completed.call(input)
                                }
                            }
                        }
                        e.preventDefault()
                    }
                }
                function clearBuffer(start, end) {
                    var i;
                    for (i = start; i < end && i < len; i++) {
                        if (tests[i]) {
                            buffer[i] = settings.placeholder
                        }
                    }
                }
                function writeBuffer() {
                    input.val(buffer.join(""))
                }
                function checkVal(allow) {
                    var test = input.val(),
                    lastMatch = -1,
                    i,
                    c;
                    for (i = 0, pos = 0; i < len; i++) {
                        if (tests[i]) {
                            buffer[i] = settings.placeholder;
                            while (pos++<test.length) {
                                c = test.charAt(pos - 1);
                                if (tests[i].test(c)) {
                                    buffer[i] = c;
                                    lastMatch = i;
                                    break
                                }
                            }
                            if (pos > test.length) {
                                break
                            }
                        } else if (buffer[i] === test.charAt(pos) && i !== partialPosition) {
                            pos++;
                            lastMatch = i
                        }
                    }
                    if (allow) {
                        writeBuffer()
                    } else if (lastMatch + 1 < partialPosition) {
                        input.val("");
                        clearBuffer(0, len)
                    } else {
                        writeBuffer();
                        input.val(input.val().substring(0, lastMatch + 1))
                    }
                    return partialPosition ? i: firstNonMaskPos
                }
                input.data($.mask.dataName,
                function() {
                    return $.map(buffer,
                    function(c, i) {
                        return tests[i] && c != settings.placeholder ? c: null
                    }).join("")
                });
                if (!input.attr("readonly")) input.one("unmask",
                function() {
                    input.unbind(".mask").removeData($.mask.dataName)
                }).bind("focus.mask",
                function() {
                    clearTimeout(caretTimeoutId);
                    var pos, moveCaret;
                    focusText = input.val();
                    pos = checkVal();
                    caretTimeoutId = setTimeout(function() {
                        writeBuffer();
                        if (pos == mask.length) {
                            input.caret(0, pos)
                        } else {
                            input.caret(pos)
                        }
                    },
                    10)
                }).bind("blur.mask",
                function() {
                    checkVal();
                    if (input.val() != focusText) input.change()
                }).bind("keydown.mask", keydownEvent).bind("keypress.mask", keypressEvent).bind(pasteEventName,
                function() {
                    setTimeout(function() {
                        var pos = checkVal(true);
                        input.caret(pos);
                        if (settings.completed && pos == input.val().length) settings.completed.call(input)
                    },
                    0)
                });
                checkVal()
            })
        }
    })
})(jQuery); (function(window, document, undefined) {
    "use strict";
    function minErr(module) {
        return function() {
            var code = arguments[0],
            prefix = "[" + (module ? module + ":": "") + code + "] ",
            template = arguments[1],
            templateArgs = arguments,
            stringify = function(obj) {
                if (isFunction(obj)) {
                    return obj.toString().replace(/ \{[\s\S]*$/, "")
                } else if (isUndefined(obj)) {
                    return "undefined"
                } else if (!isString(obj)) {
                    return JSON.stringify(obj)
                }
                return obj
            },
            message,
            i;
            message = prefix + template.replace(/\{\d+\}/g,
            function(match) {
                var index = +match.slice(1, -1),
                arg;
                if (index + 2 < templateArgs.length) {
                    arg = templateArgs[index + 2];
                    if (isFunction(arg)) {
                        return arg.toString().replace(/ ?\{[\s\S]*$/, "")
                    } else if (isUndefined(arg)) {
                        return "undefined"
                    } else if (!isString(arg)) {
                        return toJson(arg)
                    }
                    return arg
                }
                return match
            });
            message = message + "\nhttp://errors.angularjs.org/" + version.full + "/" + (module ? module + "/": "") + code;
            for (i = 2; i < arguments.length; i++) {
                message = message + (i == 2 ? "?": "&") + "p" + (i - 2) + "=" + encodeURIComponent(stringify(arguments[i]))
            }
            return new Error(message)
        }
    }
    var lowercase = function(string) {
        return isString(string) ? string.toLowerCase() : string
    };
    var uppercase = function(string) {
        return isString(string) ? string.toUpperCase() : string
    };
    var manualLowercase = function(s) {
        return isString(s) ? s.replace(/[A-Z]/g,
        function(ch) {
            return String.fromCharCode(ch.charCodeAt(0) | 32)
        }) : s
    };
    var manualUppercase = function(s) {
        return isString(s) ? s.replace(/[a-z]/g,
        function(ch) {
            return String.fromCharCode(ch.charCodeAt(0) & ~32)
        }) : s
    };
    if ("i" !== "I".toLowerCase()) {
        lowercase = manualLowercase;
        uppercase = manualUppercase
    }
    var msie, jqLite, jQuery, slice = [].slice,
    push = [].push,
    toString = Object.prototype.toString,
    ngMinErr = minErr("ng"),
    _angular = window.angular,
    angular = window.angular || (window.angular = {}),
    angularModule,
    nodeName_,
    uid = ["0", "0", "0"];
    msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
    if (isNaN(msie)) {
        msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1])
    }
    function isArrayLike(obj) {
        if (obj == null || isWindow(obj)) {
            return false
        }
        var length = obj.length;
        if (obj.nodeType === 1 && length) {
            return true
        }
        return isString(obj) || isArray(obj) || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj
    }
    function forEach(obj, iterator, context) {
        var key;
        if (obj) {
            if (isFunction(obj)) {
                for (key in obj) {
                    if (key != "prototype" && key != "length" && key != "name" && obj.hasOwnProperty(key)) {
                        iterator.call(context, obj[key], key)
                    }
                }
            } else if (obj.forEach && obj.forEach !== forEach) {
                obj.forEach(iterator, context)
            } else if (isArrayLike(obj)) {
                for (key = 0; key < obj.length; key++) iterator.call(context, obj[key], key)
            } else {
                for (key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        iterator.call(context, obj[key], key)
                    }
                }
            }
        }
        return obj
    }
    function sortedKeys(obj) {
        var keys = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                keys.push(key)
            }
        }
        return keys.sort()
    }
    function forEachSorted(obj, iterator, context) {
        var keys = sortedKeys(obj);
        for (var i = 0; i < keys.length; i++) {
            iterator.call(context, obj[keys[i]], keys[i])
        }
        return keys
    }
    function reverseParams(iteratorFn) {
        return function(value, key) {
            iteratorFn(key, value)
        }
    }
    function nextUid() {
        var index = uid.length;
        var digit;
        while (index) {
            index--;
            digit = uid[index].charCodeAt(0);
            if (digit == 57) {
                uid[index] = "A";
                return uid.join("")
            }
            if (digit == 90) {
                uid[index] = "0"
            } else {
                uid[index] = String.fromCharCode(digit + 1);
                return uid.join("")
            }
        }
        uid.unshift("0");
        return uid.join("")
    }
    function setHashKey(obj, h) {
        if (h) {
            obj.$$hashKey = h
        } else {
            delete obj.$$hashKey
        }
    }
    function extend(dst) {
        var h = dst.$$hashKey;
        forEach(arguments,
        function(obj) {
            if (obj !== dst) {
                forEach(obj,
                function(value, key) {
                    dst[key] = value
                })
            }
        });
        setHashKey(dst, h);
        return dst
    }
    function int(str) {
        return parseInt(str, 10)
    }
    function inherit(parent, extra) {
        return extend(new(extend(function() {},
        {
            prototype: parent
        })), extra)
    }
    function noop() {}
    noop.$inject = [];
    function identity($) {
        return $
    }
    identity.$inject = [];
    function valueFn(value) {
        return function() {
            return value
        }
    }
    function isUndefined(value) {
        return typeof value == "undefined"
    }
    function isDefined(value) {
        return typeof value != "undefined"
    }
    function isObject(value) {
        return value != null && typeof value == "object"
    }
    function isString(value) {
        return typeof value == "string"
    }
    function isNumber(value) {
        return typeof value == "number"
    }
    function isDate(value) {
        return toString.apply(value) == "[object Date]"
    }
    function isArray(value) {
        return toString.apply(value) == "[object Array]"
    }
    function isFunction(value) {
        return typeof value == "function"
    }
    function isRegExp(value) {
        return toString.apply(value) == "[object RegExp]"
    }
    function isWindow(obj) {
        return obj && obj.document && obj.location && obj.alert && obj.setInterval
    }
    function isScope(obj) {
        return obj && obj.$evalAsync && obj.$watch
    }
    function isFile(obj) {
        return toString.apply(obj) === "[object File]"
    }
    function isBoolean(value) {
        return typeof value == "boolean"
    }
    var trim = function() {
        if (!String.prototype.trim) {
            return function(value) {
                return isString(value) ? value.replace(/^\s*/, "").replace(/\s*$/, "") : value
            }
        }
        return function(value) {
            return isString(value) ? value.trim() : value
        }
    } ();
    function isElement(node) {
        return node && (node.nodeName || node.on && node.find)
    }
    function makeMap(str) {
        var obj = {},
        items = str.split(","),
        i;
        for (i = 0; i < items.length; i++) obj[items[i]] = true;
        return obj
    }
    if (msie < 9) {
        nodeName_ = function(element) {
            element = element.nodeName ? element: element[0];
            return element.scopeName && element.scopeName != "HTML" ? uppercase(element.scopeName + ":" + element.nodeName) : element.nodeName
        }
    } else {
        nodeName_ = function(element) {
            return element.nodeName ? element.nodeName: element[0].nodeName
        }
    }
    function map(obj, iterator, context) {
        var results = [];
        forEach(obj,
        function(value, index, list) {
            results.push(iterator.call(context, value, index, list))
        });
        return results
    }
    function size(obj, ownPropsOnly) {
        var size = 0,
        key;
        if (isArray(obj) || isString(obj)) {
            return obj.length
        } else if (isObject(obj)) {
            for (key in obj) if (!ownPropsOnly || obj.hasOwnProperty(key)) size++
        }
        return size
    }
    function includes(array, obj) {
        return indexOf(array, obj) != -1
    }
    function indexOf(array, obj) {
        if (array.indexOf) return array.indexOf(obj);
        for (var i = 0; i < array.length; i++) {
            if (obj === array[i]) return i
        }
        return - 1
    }
    function arrayRemove(array, value) {
        var index = indexOf(array, value);
        if (index >= 0) array.splice(index, 1);
        return value
    }
    function isLeafNode(node) {
        if (node) {
            switch (node.nodeName) {
            case "OPTION":
            case "PRE":
            case "TITLE":
                return true
            }
        }
        return false
    }
    function copy(source, destination) {
        if (isWindow(source) || isScope(source)) {
            throw ngMinErr("cpws", "Can't copy! Making copies of Window or Scope instances is not supported.")
        }
        if (!destination) {
            destination = source;
            if (source) {
                if (isArray(source)) {
                    destination = copy(source, [])
                } else if (isDate(source)) {
                    destination = new Date(source.getTime())
                } else if (isRegExp(source)) {
                    destination = new RegExp(source.source)
                } else if (isObject(source)) {
                    destination = copy(source, {})
                }
            }
        } else {
            if (source === destination) throw ngMinErr("cpi", "Can't copy! Source and destination are identical.");
            if (isArray(source)) {
                destination.length = 0;
                for (var i = 0; i < source.length; i++) {
                    destination.push(copy(source[i]))
                }
            } else {
                var h = destination.$$hashKey;
                forEach(destination,
                function(value, key) {
                    delete destination[key]
                });
                for (var key in source) {
                    destination[key] = copy(source[key])
                }
                setHashKey(destination, h)
            }
        }
        return destination
    }
    function shallowCopy(src, dst) {
        dst = dst || {};
        for (var key in src) {
            if (src.hasOwnProperty(key) && key.substr(0, 2) !== "$$") {
                dst[key] = src[key]
            }
        }
        return dst
    }
    function equals(o1, o2) {
        if (o1 === o2) return true;
        if (o1 === null || o2 === null) return false;
        if (o1 !== o1 && o2 !== o2) return true;
        var t1 = typeof o1,
        t2 = typeof o2,
        length, key, keySet;
        if (t1 == t2) {
            if (t1 == "object") {
                if (isArray(o1)) {
                    if (!isArray(o2)) return false;
                    if ((length = o1.length) == o2.length) {
                        for (key = 0; key < length; key++) {
                            if (!equals(o1[key], o2[key])) return false
                        }
                        return true
                    }
                } else if (isDate(o1)) {
                    return isDate(o2) && o1.getTime() == o2.getTime()
                } else if (isRegExp(o1) && isRegExp(o2)) {
                    return o1.toString() == o2.toString()
                } else {
                    if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
                    keySet = {};
                    for (key in o1) {
                        if (key.charAt(0) === "$" || isFunction(o1[key])) continue;
                        if (!equals(o1[key], o2[key])) return false;
                        keySet[key] = true
                    }
                    for (key in o2) {
                        if (!keySet.hasOwnProperty(key) && key.charAt(0) !== "$" && o2[key] !== undefined && !isFunction(o2[key])) return false
                    }
                    return true
                }
            }
        }
        return false
    }
    function concat(array1, array2, index) {
        return array1.concat(slice.call(array2, index))
    }
    function sliceArgs(args, startIndex) {
        return slice.call(args, startIndex || 0)
    }
    function bind(self, fn) {
        var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
        if (isFunction(fn) && !(fn instanceof RegExp)) {
            return curryArgs.length ?
            function() {
                return arguments.length ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0))) : fn.apply(self, curryArgs)
            }: function() {
                return arguments.length ? fn.apply(self, arguments) : fn.call(self)
            }
        } else {
            return fn
        }
    }
    function toJsonReplacer(key, value) {
        var val = value;
        if (typeof key === "string" && key.charAt(0) === "$") {
            val = undefined
        } else if (isWindow(value)) {
            val = "$WINDOW"
        } else if (value && document === value) {
            val = "$DOCUMENT"
        } else if (isScope(value)) {
            val = "$SCOPE"
        }
        return val
    }
    function toJson(obj, pretty) {
        if (typeof obj === "undefined") return undefined;
        return JSON.stringify(obj, toJsonReplacer, pretty ? "  ": null)
    }
    function fromJson(json) {
        return isString(json) ? JSON.parse(json) : json
    }
    function toBoolean(value) {
        if (value && value.length !== 0) {
            var v = lowercase("" + value);
            value = !(v == "f" || v == "0" || v == "false" || v == "no" || v == "n" || v == "[]")
        } else {
            value = false
        }
        return value
    }
    function startingTag(element) {
        element = jqLite(element).clone();
        try {
            element.html("")
        } catch(e) {}
        var TEXT_NODE = 3;
        var elemHtml = jqLite("<div>").append(element).html();
        try {
            return element[0].nodeType === TEXT_NODE ? lowercase(elemHtml) : elemHtml.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,
            function(match, nodeName) {
                return "<" + lowercase(nodeName)
            })
        } catch(e) {
            return lowercase(elemHtml)
        }
    }
    function tryDecodeURIComponent(value) {
        try {
            return decodeURIComponent(value)
        } catch(e) {}
    }
    function parseKeyValue(keyValue) {
        var obj = {},
        key_value, key;
        forEach((keyValue || "").split("&"),
        function(keyValue) {
            if (keyValue) {
                key_value = keyValue.split("=");
                key = tryDecodeURIComponent(key_value[0]);
                if (isDefined(key)) {
                    var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
                    if (!obj[key]) {
                        obj[key] = val
                    } else if (isArray(obj[key])) {
                        obj[key].push(val)
                    } else {
                        obj[key] = [obj[key], val]
                    }
                }
            }
        });
        return obj
    }
    function toKeyValue(obj) {
        var parts = [];
        forEach(obj,
        function(value, key) {
            if (isArray(value)) {
                forEach(value,
                function(arrayValue) {
                    parts.push(encodeUriQuery(key, true) + (arrayValue === true ? "": "=" + encodeUriQuery(arrayValue, true)))
                })
            } else {
                parts.push(encodeUriQuery(key, true) + (value === true ? "": "=" + encodeUriQuery(value, true)))
            }
        });
        return parts.length ? parts.join("&") : ""
    }
    function encodeUriSegment(val) {
        return encodeUriQuery(val, true).replace(/%26/gi, "&").replace(/%3D/gi, "=").replace(/%2B/gi, "+")
    }
    function encodeUriQuery(val, pctEncodeSpaces) {
        return encodeURIComponent(val).replace(/%40/gi, "@").replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, pctEncodeSpaces ? "%20": "+")
    }
    function angularInit(element, bootstrap) {
        var elements = [element],
        appElement,
        module,
        names = ["ng:app", "ng-app", "x-ng-app", "data-ng-app"],
        NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
        function append(element) {
            element && elements.push(element)
        }
        forEach(names,
        function(name) {
            names[name] = true;
            append(document.getElementById(name));
            name = name.replace(":", "\\:");
            if (element.querySelectorAll) {
                forEach(element.querySelectorAll("." + name), append);
                forEach(element.querySelectorAll("." + name + "\\:"), append);
                forEach(element.querySelectorAll("[" + name + "]"), append)
            }
        });
        forEach(elements,
        function(element) {
            if (!appElement) {
                var className = " " + element.className + " ";
                var match = NG_APP_CLASS_REGEXP.exec(className);
                if (match) {
                    appElement = element;
                    module = (match[2] || "").replace(/\s+/g, ",")
                } else {
                    forEach(element.attributes,
                    function(attr) {
                        if (!appElement && names[attr.name]) {
                            appElement = element;
                            module = attr.value
                        }
                    })
                }
            }
        });
        if (appElement) {
            bootstrap(appElement, module ? [module] : [])
        }
    }
    function bootstrap(element, modules) {
        var doBootstrap = function() {
            element = jqLite(element);
            if (element.injector()) {
                var tag = element[0] === document ? "document": startingTag(element);
                throw ngMinErr("btstrpd", "App Already Bootstrapped with this Element '{0}'", tag)
            }
            modules = modules || [];
            modules.unshift(["$provide",
            function($provide) {
                $provide.value("$rootElement", element)
            }]);
            modules.unshift("ng");
            var injector = createInjector(modules);
            injector.invoke(["$rootScope", "$rootElement", "$compile", "$injector", "$animate",
            function(scope, element, compile, injector, animate) {
                scope.$apply(function() {
                    element.data("$injector", injector);
                    compile(element)(scope)
                });
                animate.enabled(true)
            }]);
            return injector
        };
        var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
        if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
            return doBootstrap()
        }
        window.name = window.name.replace(NG_DEFER_BOOTSTRAP, "");
        angular.resumeBootstrap = function(extraModules) {
            forEach(extraModules,
            function(module) {
                modules.push(module)
            });
            doBootstrap()
        }
    }
    var SNAKE_CASE_REGEXP = /[A-Z]/g;
    function snake_case(name, separator) {
        separator = separator || "_";
        return name.replace(SNAKE_CASE_REGEXP,
        function(letter, pos) {
            return (pos ? separator: "") + letter.toLowerCase()
        })
    }
    function bindJQuery() {
        jQuery = window.jQuery;
        if (jQuery) {
            jqLite = jQuery;
            extend(jQuery.fn, {
                scope: JQLitePrototype.scope,
                controller: JQLitePrototype.controller,
                injector: JQLitePrototype.injector,
                inheritedData: JQLitePrototype.inheritedData
            });
            JQLitePatchJQueryRemove("remove", true, true, false);
            JQLitePatchJQueryRemove("empty", false, false, false);
            JQLitePatchJQueryRemove("html", false, false, true)
        } else {
            jqLite = JQLite
        }
        angular.element = jqLite
    }
    function assertArg(arg, name, reason) {
        if (!arg) {
            throw ngMinErr("areq", "Argument '{0}' is {1}", name || "?", reason || "required")
        }
        return arg
    }
    function assertArgFn(arg, name, acceptArrayAnnotation) {
        if (acceptArrayAnnotation && isArray(arg)) {
            arg = arg[arg.length - 1]
        }
        assertArg(isFunction(arg), name, "not a function, got " + (arg && typeof arg == "object" ? arg.constructor.name || "Object": typeof arg));
        return arg
    }
    function assertNotHasOwnProperty(name, context) {
        if (name === "hasOwnProperty") {
            throw ngMinErr("badname", "hasOwnProperty is not a valid {0} name", context)
        }
    }
    function getter(obj, path, bindFnToScope) {
        if (!path) return obj;
        var keys = path.split(".");
        var key;
        var lastInstance = obj;
        var len = keys.length;
        for (var i = 0; i < len; i++) {
            key = keys[i];
            if (obj) {
                obj = (lastInstance = obj)[key]
            }
        }
        if (!bindFnToScope && isFunction(obj)) {
            return bind(lastInstance, obj)
        }
        return obj
    }
    function setupModuleLoader(window) {
        var $injectorMinErr = minErr("$injector");
        function ensure(obj, name, factory) {
            return obj[name] || (obj[name] = factory())
        }
        return ensure(ensure(window, "angular", Object), "module",
        function() {
            var modules = {};
            return function module(name, requires, configFn) {
                assertNotHasOwnProperty(name, "module");
                if (requires && modules.hasOwnProperty(name)) {
                    modules[name] = null
                }
                return ensure(modules, name,
                function() {
                    if (!requires) {
                        throw $injectorMinErr("nomod", "Module '{0}' is not available! You either misspelled the module name " + "or forgot to load it. If registering a module ensure that you specify the dependencies as the second " + "argument.", name)
                    }
                    var invokeQueue = [];
                    var runBlocks = [];
                    var config = invokeLater("$injector", "invoke");
                    var moduleInstance = {
                        _invokeQueue: invokeQueue,
                        _runBlocks: runBlocks,
                        requires: requires,
                        name: name,
                        provider: invokeLater("$provide", "provider"),
                        factory: invokeLater("$provide", "factory"),
                        service: invokeLater("$provide", "service"),
                        value: invokeLater("$provide", "value"),
                        constant: invokeLater("$provide", "constant", "unshift"),
                        animation: invokeLater("$animateProvider", "register"),
                        filter: invokeLater("$filterProvider", "register"),
                        controller: invokeLater("$controllerProvider", "register"),
                        directive: invokeLater("$compileProvider", "directive"),
                        config: config,
                        run: function(block) {
                            runBlocks.push(block);
                            return this
                        }
                    };
                    if (configFn) {
                        config(configFn)
                    }
                    return moduleInstance;
                    function invokeLater(provider, method, insertMethod) {
                        return function() {
                            invokeQueue[insertMethod || "push"]([provider, method, arguments]);
                            return moduleInstance
                        }
                    }
                })
            }
        })
    }
    var version = {
        full: "1.2.0-rc.3",
        major: 1,
        minor: 2,
        dot: 0,
        codeName: "ferocious-twitch"
    };
    function publishExternalAPI(angular) {
        extend(angular, {
            bootstrap: bootstrap,
            copy: copy,
            extend: extend,
            equals: equals,
            element: jqLite,
            forEach: forEach,
            injector: createInjector,
            noop: noop,
            bind: bind,
            toJson: toJson,
            fromJson: fromJson,
            identity: identity,
            isUndefined: isUndefined,
            isDefined: isDefined,
            isString: isString,
            isFunction: isFunction,
            isObject: isObject,
            isNumber: isNumber,
            isElement: isElement,
            isArray: isArray,
            $$minErr: minErr,
            version: version,
            isDate: isDate,
            lowercase: lowercase,
            uppercase: uppercase,
            callbacks: {
                counter: 0
            }
        });
        angularModule = setupModuleLoader(window);
        try {
            angularModule("ngLocale")
        } catch(e) {
            angularModule("ngLocale", []).provider("$locale", $LocaleProvider)
        }
        angularModule("ng", ["ngLocale"], ["$provide",
        function ngModule($provide) {
            $provide.provider("$compile", $CompileProvider).directive({
                a: htmlAnchorDirective,
                input: inputDirective,
                textarea: inputDirective,
                form: formDirective,
                script: scriptDirective,
                select: selectDirective,
                style: styleDirective,
                option: optionDirective,
                ngBind: ngBindDirective,
                ngBindHtml: ngBindHtmlDirective,
                ngBindTemplate: ngBindTemplateDirective,
                ngClass: ngClassDirective,
                ngClassEven: ngClassEvenDirective,
                ngClassOdd: ngClassOddDirective,
                ngCsp: ngCspDirective,
                ngCloak: ngCloakDirective,
                ngController: ngControllerDirective,
                ngForm: ngFormDirective,
                ngHide: ngHideDirective,
                ngIf: ngIfDirective,
                ngInclude: ngIncludeDirective,
                ngInit: ngInitDirective,
                ngNonBindable: ngNonBindableDirective,
                ngPluralize: ngPluralizeDirective,
                ngRepeat: ngRepeatDirective,
                ngShow: ngShowDirective,
                ngStyle: ngStyleDirective,
                ngSwitch: ngSwitchDirective,
                ngSwitchWhen: ngSwitchWhenDirective,
                ngSwitchDefault: ngSwitchDefaultDirective,
                ngOptions: ngOptionsDirective,
                ngTransclude: ngTranscludeDirective,
                ngModel: ngModelDirective,
                ngList: ngListDirective,
                ngChange: ngChangeDirective,
                required: requiredDirective,
                ngRequired: requiredDirective,
                ngValue: ngValueDirective
            }).directive(ngAttributeAliasDirectives).directive(ngEventDirectives);
            $provide.provider({
                $anchorScroll: $AnchorScrollProvider,
                $animate: $AnimateProvider,
                $browser: $BrowserProvider,
                $cacheFactory: $CacheFactoryProvider,
                $controller: $ControllerProvider,
                $document: $DocumentProvider,
                $exceptionHandler: $ExceptionHandlerProvider,
                $filter: $FilterProvider,
                $interpolate: $InterpolateProvider,
                $interval: $IntervalProvider,
                $http: $HttpProvider,
                $httpBackend: $HttpBackendProvider,
                $location: $LocationProvider,
                $log: $LogProvider,
                $parse: $ParseProvider,
                $rootScope: $RootScopeProvider,
                $q: $QProvider,
                $sce: $SceProvider,
                $sceDelegate: $SceDelegateProvider,
                $sniffer: $SnifferProvider,
                $templateCache: $TemplateCacheProvider,
                $timeout: $TimeoutProvider,
                $window: $WindowProvider
            })
        }])
    }
    var jqCache = JQLite.cache = {},
    jqName = JQLite.expando = "ng-" + (new Date).getTime(),
    jqId = 1,
    addEventListenerFn = window.document.addEventListener ?
    function(element, type, fn) {
        element.addEventListener(type, fn, false)
    }: function(element, type, fn) {
        element.attachEvent("on" + type, fn)
    },
    removeEventListenerFn = window.document.removeEventListener ?
    function(element, type, fn) {
        element.removeEventListener(type, fn, false)
    }: function(element, type, fn) {
        element.detachEvent("on" + type, fn)
    };
    function jqNextId() {
        return++jqId
    }
    var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
    var MOZ_HACK_REGEXP = /^moz([A-Z])/;
    var jqLiteMinErr = minErr("jqLite");
    function camelCase(name) {
        return name.replace(SPECIAL_CHARS_REGEXP,
        function(_, separator, letter, offset) {
            return offset ? letter.toUpperCase() : letter
        }).replace(MOZ_HACK_REGEXP, "Moz$1")
    }
    function JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) {
        var originalJqFn = jQuery.fn[name];
        originalJqFn = originalJqFn.$original || originalJqFn;
        removePatch.$original = originalJqFn;
        jQuery.fn[name] = removePatch;
        function removePatch(param) {
            var list = filterElems && param ? [this.filter(param)] : [this],
            fireEvent = dispatchThis,
            set,
            setIndex,
            setLength,
            element,
            childIndex,
            childLength,
            children;
            if (!getterIfNoArguments || param != null) {
                while (list.length) {
                    set = list.shift();
                    for (setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
                        element = jqLite(set[setIndex]);
                        if (fireEvent) {
                            element.triggerHandler("$destroy")
                        } else {
                            fireEvent = !fireEvent
                        }
                        for (childIndex = 0, childLength = (children = element.children()).length; childIndex < childLength; childIndex++) {
                            list.push(jQuery(children[childIndex]))
                        }
                    }
                }
            }
            return originalJqFn.apply(this, arguments)
        }
    }
    function JQLite(element) {
        if (element instanceof JQLite) {
            return element
        }
        if (! (this instanceof JQLite)) {
            if (isString(element) && element.charAt(0) != "<") {
                throw jqLiteMinErr("nosel", "Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element")
            }
            return new JQLite(element)
        }
        if (isString(element)) {
            var div = document.createElement("div");
            div.innerHTML = "<div>&#160;</div>" + element;
            div.removeChild(div.firstChild);
            JQLiteAddNodes(this, div.childNodes);
            var fragment = jqLite(document.createDocumentFragment());
            fragment.append(this)
        } else {
            JQLiteAddNodes(this, element)
        }
    }
    function JQLiteClone(element) {
        return element.cloneNode(true)
    }
    function JQLiteDealoc(element) {
        JQLiteRemoveData(element);
        for (var i = 0,
        children = element.childNodes || []; i < children.length; i++) {
            JQLiteDealoc(children[i])
        }
    }
    function JQLiteOff(element, type, fn, unsupported) {
        if (isDefined(unsupported)) throw jqLiteMinErr("offargs", "jqLite#off() does not support the `selector` argument");
        var events = JQLiteExpandoStore(element, "events"),
        handle = JQLiteExpandoStore(element, "handle");
        if (!handle) return;
        if (isUndefined(type)) {
            forEach(events,
            function(eventHandler, type) {
                removeEventListenerFn(element, type, eventHandler);
                delete events[type]
            })
        } else {
            forEach(type.split(" "),
            function(type) {
                if (isUndefined(fn)) {
                    removeEventListenerFn(element, type, events[type]);
                    delete events[type]
                } else {
                    arrayRemove(events[type] || [], fn)
                }
            })
        }
    }
    function JQLiteRemoveData(element, name) {
        var expandoId = element[jqName],
        expandoStore = jqCache[expandoId];
        if (expandoStore) {
            if (name) {
                delete jqCache[expandoId].data[name];
                return
            }
            if (expandoStore.handle) {
                expandoStore.events.$destroy && expandoStore.handle({},
                "$destroy");
                JQLiteOff(element)
            }
            delete jqCache[expandoId];
            element[jqName] = undefined
        }
    }
    function JQLiteExpandoStore(element, key, value) {
        var expandoId = element[jqName],
        expandoStore = jqCache[expandoId || -1];
        if (isDefined(value)) {
            if (!expandoStore) {
                element[jqName] = expandoId = jqNextId();
                expandoStore = jqCache[expandoId] = {}
            }
            expandoStore[key] = value
        } else {
            return expandoStore && expandoStore[key]
        }
    }
    function JQLiteData(element, key, value) {
        var data = JQLiteExpandoStore(element, "data"),
        isSetter = isDefined(value),
        keyDefined = !isSetter && isDefined(key),
        isSimpleGetter = keyDefined && !isObject(key);
        if (!data && !isSimpleGetter) {
            JQLiteExpandoStore(element, "data", data = {})
        }
        if (isSetter) {
            data[key] = value
        } else {
            if (keyDefined) {
                if (isSimpleGetter) {
                    return data && data[key]
                } else {
                    extend(data, key)
                }
            } else {
                return data
            }
        }
    }
    function JQLiteHasClass(element, selector) {
        if (!element.getAttribute) return false;
        return (" " + (element.getAttribute("class") || "") + " ").replace(/[\n\t]/g, " ").indexOf(" " + selector + " ") > -1
    }
    function JQLiteRemoveClass(element, cssClasses) {
        if (cssClasses && element.setAttribute) {
            forEach(cssClasses.split(" "),
            function(cssClass) {
                element.setAttribute("class", trim((" " + (element.getAttribute("class") || "") + " ").replace(/[\n\t]/g, " ").replace(" " + trim(cssClass) + " ", " ")))
            })
        }
    }
    function JQLiteAddClass(element, cssClasses) {
        if (cssClasses && element.setAttribute) {
            var existingClasses = (" " + (element.getAttribute("class") || "") + " ").replace(/[\n\t]/g, " ");
            forEach(cssClasses.split(" "),
            function(cssClass) {
                cssClass = trim(cssClass);
                if (existingClasses.indexOf(" " + cssClass + " ") === -1) {
                    existingClasses += cssClass + " "
                }
            });
            element.setAttribute("class", trim(existingClasses))
        }
    }
    function JQLiteAddNodes(root, elements) {
        if (elements) {
            elements = !elements.nodeName && isDefined(elements.length) && !isWindow(elements) ? elements: [elements];
            for (var i = 0; i < elements.length; i++) {
                root.push(elements[i])
            }
        }
    }
    function JQLiteController(element, name) {
        return JQLiteInheritedData(element, "$" + (name || "ngController") + "Controller")
    }
    function JQLiteInheritedData(element, name, value) {
        element = jqLite(element);
        if (element[0].nodeType == 9) {
            element = element.find("html")
        }
        while (element.length) {
            if ((value = element.data(name)) !== undefined) return value;
            element = element.parent()
        }
    }
    var JQLitePrototype = JQLite.prototype = {
        ready: function(fn) {
            var fired = false;
            function trigger() {
                if (fired) return;
                fired = true;
                fn()
            }
            if (document.readyState === "complete") {
                setTimeout(trigger)
            } else {
                this.on("DOMContentLoaded", trigger);
                JQLite(window).on("load", trigger)
            }
        },
        toString: function() {
            var value = [];
            forEach(this,
            function(e) {
                value.push("" + e)
            });
            return "[" + value.join(", ") + "]"
        },
        eq: function(index) {
            return index >= 0 ? jqLite(this[index]) : jqLite(this[this.length + index])
        },
        length: 0,
        push: push,
        sort: [].sort,
        splice: [].splice
    };
    var BOOLEAN_ATTR = {};
    forEach("multiple,selected,checked,disabled,readOnly,required,open".split(","),
    function(value) {
        BOOLEAN_ATTR[lowercase(value)] = value
    });
    var BOOLEAN_ELEMENTS = {};
    forEach("input,select,option,textarea,button,form,details".split(","),
    function(value) {
        BOOLEAN_ELEMENTS[uppercase(value)] = true
    });
    function getBooleanAttrName(element, name) {
        var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
        return booleanAttr && BOOLEAN_ELEMENTS[element.nodeName] && booleanAttr
    }
    forEach({
        data: JQLiteData,
        inheritedData: JQLiteInheritedData,
        scope: function(element) {
            return JQLiteInheritedData(element, "$scope")
        },
        controller: JQLiteController,
        injector: function(element) {
            return JQLiteInheritedData(element, "$injector")
        },
        removeAttr: function(element, name) {
            element.removeAttribute(name)
        },
        hasClass: JQLiteHasClass,
        css: function(element, name, value) {
            name = camelCase(name);
            if (isDefined(value)) {
                element.style[name] = value
            } else {
                var val;
                if (msie <= 8) {
                    val = element.currentStyle && element.currentStyle[name];
                    if (val === "") val = "auto"
                }
                val = val || element.style[name];
                if (msie <= 8) {
                    val = val === "" ? undefined: val
                }
                return val
            }
        },
        attr: function(element, name, value) {
            var lowercasedName = lowercase(name);
            if (BOOLEAN_ATTR[lowercasedName]) {
                if (isDefined(value)) {
                    if ( !! value) {
                        element[name] = true;
                        element.setAttribute(name, lowercasedName)
                    } else {
                        element[name] = false;
                        element.removeAttribute(lowercasedName)
                    }
                } else {
                    return element[name] || (element.attributes.getNamedItem(name) || noop).specified ? lowercasedName: undefined
                }
            } else if (isDefined(value)) {
                element.setAttribute(name, value)
            } else if (element.getAttribute) {
                var ret = element.getAttribute(name, 2);
                return ret === null ? undefined: ret
            }
        },
        prop: function(element, name, value) {
            if (isDefined(value)) {
                element[name] = value
            } else {
                return element[name]
            }
        },
        text: function() {
            var NODE_TYPE_TEXT_PROPERTY = [];
            if (msie < 9) {
                NODE_TYPE_TEXT_PROPERTY[1] = "innerText";
                NODE_TYPE_TEXT_PROPERTY[3] = "nodeValue"
            } else {
                NODE_TYPE_TEXT_PROPERTY[1] = NODE_TYPE_TEXT_PROPERTY[3] = "textContent"
            }
            getText.$dv = "";
            return getText;
            function getText(element, value) {
                var textProp = NODE_TYPE_TEXT_PROPERTY[element.nodeType];
                if (isUndefined(value)) {
                    return textProp ? element[textProp] : ""
                }
                element[textProp] = value
            }
        } (),
        val: function(element, value) {
            if (isUndefined(value)) {
                if (nodeName_(element) === "SELECT" && element.multiple) {
                    var result = [];
                    forEach(element.options,
                    function(option) {
                        if (option.selected) {
                            result.push(option.value || option.text)
                        }
                    });
                    return result.length === 0 ? null: result
                }
                return element.value
            }
            element.value = value
        },
        html: function(element, value) {
            if (isUndefined(value)) {
                return element.innerHTML
            }
            for (var i = 0,
            childNodes = element.childNodes; i < childNodes.length; i++) {
                JQLiteDealoc(childNodes[i])
            }
            element.innerHTML = value
        }
    },
    function(fn, name) {
        JQLite.prototype[name] = function(arg1, arg2) {
            var i, key;
            if ((fn.length == 2 && (fn !== JQLiteHasClass && fn !== JQLiteController) ? arg1: arg2) === undefined) {
                if (isObject(arg1)) {
                    for (i = 0; i < this.length; i++) {
                        if (fn === JQLiteData) {
                            fn(this[i], arg1)
                        } else {
                            for (key in arg1) {
                                fn(this[i], key, arg1[key])
                            }
                        }
                    }
                    return this
                } else {
                    var value = fn.$dv;
                    var jj = value == undefined ? Math.min(this.length, 1) : this.length;
                    for (var j = 0; j < jj; j++) {
                        var nodeValue = fn(this[j], arg1, arg2);
                        value = value ? value + nodeValue: nodeValue
                    }
                    return value
                }
            } else {
                for (i = 0; i < this.length; i++) {
                    fn(this[i], arg1, arg2)
                }
                return this
            }
        }
    });
    function createEventHandler(element, events) {
        var eventHandler = function(event, type) {
            if (!event.preventDefault) {
                event.preventDefault = function() {
                    event.returnValue = false
                }
            }
            if (!event.stopPropagation) {
                event.stopPropagation = function() {
                    event.cancelBubble = true
                }
            }
            if (!event.target) {
                event.target = event.srcElement || document
            }
            if (isUndefined(event.defaultPrevented)) {
                var prevent = event.preventDefault;
                event.preventDefault = function() {
                    event.defaultPrevented = true;
                    prevent.call(event)
                };
                event.defaultPrevented = false
            }
            event.isDefaultPrevented = function() {
                return event.defaultPrevented || event.returnValue == false
            };
            forEach(events[type || event.type],
            function(fn) {
                fn.call(element, event)
            });
            if (msie <= 8) {
                event.preventDefault = null;
                event.stopPropagation = null;
                event.isDefaultPrevented = null
            } else {
                delete event.preventDefault;
                delete event.stopPropagation;
                delete event.isDefaultPrevented
            }
        };
        eventHandler.elem = element;
        return eventHandler
    }
    forEach({
        removeData: JQLiteRemoveData,
        dealoc: JQLiteDealoc,
        on: function onFn(element, type, fn, unsupported) {
            if (isDefined(unsupported)) throw jqLiteMinErr("onargs", "jqLite#on() does not support the `selector` or `eventData` parameters");
            var events = JQLiteExpandoStore(element, "events"),
            handle = JQLiteExpandoStore(element, "handle");
            if (!events) JQLiteExpandoStore(element, "events", events = {});
            if (!handle) JQLiteExpandoStore(element, "handle", handle = createEventHandler(element, events));
            forEach(type.split(" "),
            function(type) {
                var eventFns = events[type];
                if (!eventFns) {
                    if (type == "mouseenter" || type == "mouseleave") {
                        var contains = document.body.contains || document.body.compareDocumentPosition ?
                        function(a, b) {
                            var adown = a.nodeType === 9 ? a.documentElement: a,
                            bup = b && b.parentNode;
                            return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16))
                        }: function(a, b) {
                            if (b) {
                                while (b = b.parentNode) {
                                    if (b === a) {
                                        return true
                                    }
                                }
                            }
                            return false
                        };
                        events[type] = [];
                        var eventmap = {
                            mouseleave: "mouseout",
                            mouseenter: "mouseover"
                        };
                        onFn(element, eventmap[type],
                        function(event) {
                            var target = this,
                            related = event.relatedTarget;
                            if (!related || related !== target && !contains(target, related)) {
                                handle(event, type)
                            }
                        })
                    } else {
                        addEventListenerFn(element, type, handle);
                        events[type] = []
                    }
                    eventFns = events[type]
                }
                eventFns.push(fn)
            })
        },
        off: JQLiteOff,
        replaceWith: function(element, replaceNode) {
            var index, parent = element.parentNode;
            JQLiteDealoc(element);
            forEach(new JQLite(replaceNode),
            function(node) {
                if (index) {
                    parent.insertBefore(node, index.nextSibling)
                } else {
                    parent.replaceChild(node, element)
                }
                index = node
            })
        },
        children: function(element) {
            var children = [];
            forEach(element.childNodes,
            function(element) {
                if (element.nodeType === 1) children.push(element)
            });
            return children
        },
        contents: function(element) {
            return element.childNodes || []
        },
        append: function(element, node) {
            forEach(new JQLite(node),
            function(child) {
                if (element.nodeType === 1 || element.nodeType === 11) {
                    element.appendChild(child)
                }
            })
        },
        prepend: function(element, node) {
            if (element.nodeType === 1) {
                var index = element.firstChild;
                forEach(new JQLite(node),
                function(child) {
                    element.insertBefore(child, index)
                })
            }
        },
        wrap: function(element, wrapNode) {
            wrapNode = jqLite(wrapNode)[0];
            var parent = element.parentNode;
            if (parent) {
                parent.replaceChild(wrapNode, element)
            }
            wrapNode.appendChild(element)
        },
        remove: function(element) {
            JQLiteDealoc(element);
            var parent = element.parentNode;
            if (parent) parent.removeChild(element)
        },
        after: function(element, newElement) {
            var index = element,
            parent = element.parentNode;
            forEach(new JQLite(newElement),
            function(node) {
                parent.insertBefore(node, index.nextSibling);
                index = node
            })
        },
        addClass: JQLiteAddClass,
        removeClass: JQLiteRemoveClass,
        toggleClass: function(element, selector, condition) {
            if (isUndefined(condition)) {
                condition = !JQLiteHasClass(element, selector)
            } (condition ? JQLiteAddClass: JQLiteRemoveClass)(element, selector)
        },
        parent: function(element) {
            var parent = element.parentNode;
            return parent && parent.nodeType !== 11 ? parent: null
        },
        next: function(element) {
            if (element.nextElementSibling) {
                return element.nextElementSibling
            }
            var elm = element.nextSibling;
            while (elm != null && elm.nodeType !== 1) {
                elm = elm.nextSibling
            }
            return elm
        },
        find: function(element, selector) {
            return element.getElementsByTagName(selector)
        },
        clone: JQLiteClone,
        triggerHandler: function(element, eventName, eventData) {
            var eventFns = (JQLiteExpandoStore(element, "events") || {})[eventName];
            eventData = eventData || [];
            var event = [{
                preventDefault: noop,
                stopPropagation: noop
            }];
            forEach(eventFns,
            function(fn) {
                fn.apply(element, event.concat(eventData))
            })
        }
    },
    function(fn, name) {
        JQLite.prototype[name] = function(arg1, arg2, arg3) {
            var value;
            for (var i = 0; i < this.length; i++) {
                if (value == undefined) {
                    value = fn(this[i], arg1, arg2, arg3);
                    if (value !== undefined) {
                        value = jqLite(value)
                    }
                } else {
                    JQLiteAddNodes(value, fn(this[i], arg1, arg2, arg3))
                }
            }
            return value == undefined ? this: value
        };
        JQLite.prototype.bind = JQLite.prototype.on;
        JQLite.prototype.unbind = JQLite.prototype.off
    });
    function hashKey(obj) {
        var objType = typeof obj,
        key;
        if (objType == "object" && obj !== null) {
            if (typeof(key = obj.$$hashKey) == "function") {
                key = obj.$$hashKey()
            } else if (key === undefined) {
                key = obj.$$hashKey = nextUid()
            }
        } else {
            key = obj
        }
        return objType + ":" + key
    }
    function HashMap(array) {
        forEach(array, this.put, this)
    }
    HashMap.prototype = {
        put: function(key, value) {
            this[hashKey(key)] = value
        },
        get: function(key) {
            return this[hashKey(key)]
        },
        remove: function(key) {
            var value = this[key = hashKey(key)];
            delete this[key];
            return value
        }
    };
    var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
    var FN_ARG_SPLIT = /,/;
    var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
    var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
    var $injectorMinErr = minErr("$injector");
    function annotate(fn) {
        var $inject, fnText, argDecl, last;
        if (typeof fn == "function") {
            if (! ($inject = fn.$inject)) {
                $inject = [];
                if (fn.length) {
                    fnText = fn.toString().replace(STRIP_COMMENTS, "");
                    argDecl = fnText.match(FN_ARGS);
                    forEach(argDecl[1].split(FN_ARG_SPLIT),
                    function(arg) {
                        arg.replace(FN_ARG,
                        function(all, underscore, name) {
                            $inject.push(name)
                        })
                    })
                }
                fn.$inject = $inject
            }
        } else if (isArray(fn)) {
            last = fn.length - 1;
            assertArgFn(fn[last], "fn");
            $inject = fn.slice(0, last)
        } else {
            assertArgFn(fn, "fn", true)
        }
        return $inject
    }
    function createInjector(modulesToLoad) {
        var INSTANTIATING = {},
        providerSuffix = "Provider",
        path = [],
        loadedModules = new HashMap,
        providerCache = {
            $provide: {
                provider: supportObject(provider),
                factory: supportObject(factory),
                service: supportObject(service),
                value: supportObject(value),
                constant: supportObject(constant),
                decorator: decorator
            }
        },
        providerInjector = providerCache.$injector = createInternalInjector(providerCache,
        function() {
            throw $injectorMinErr("unpr", "Unknown provider: {0}", path.join(" <- "))
        }),
        instanceCache = {},
        instanceInjector = instanceCache.$injector = createInternalInjector(instanceCache,
        function(servicename) {
            var provider = providerInjector.get(servicename + providerSuffix);
            return instanceInjector.invoke(provider.$get, provider)
        });
        forEach(loadModules(modulesToLoad),
        function(fn) {
            instanceInjector.invoke(fn || noop)
        });
        return instanceInjector;
        function supportObject(delegate) {
            return function(key, value) {
                if (isObject(key)) {
                    forEach(key, reverseParams(delegate))
                } else {
                    return delegate(key, value)
                }
            }
        }
        function provider(name, provider_) {
            assertNotHasOwnProperty(name, "service");
            if (isFunction(provider_) || isArray(provider_)) {
                provider_ = providerInjector.instantiate(provider_)
            }
            if (!provider_.$get) {
                throw $injectorMinErr("pget", "Provider '{0}' must define $get factory method.", name)
            }
            return providerCache[name + providerSuffix] = provider_
        }
        function factory(name, factoryFn) {
            return provider(name, {
                $get: factoryFn
            })
        }
        function service(name, constructor) {
            return factory(name, ["$injector",
            function($injector) {
                return $injector.instantiate(constructor)
            }])
        }
        function value(name, value) {
            return factory(name, valueFn(value))
        }
        function constant(name, value) {
            assertNotHasOwnProperty(name, "constant");
            providerCache[name] = value;
            instanceCache[name] = value
        }
        function decorator(serviceName, decorFn) {
            var origProvider = providerInjector.get(serviceName + providerSuffix),
            orig$get = origProvider.$get;
            origProvider.$get = function() {
                var origInstance = instanceInjector.invoke(orig$get, origProvider);
                return instanceInjector.invoke(decorFn, null, {
                    $delegate: origInstance
                })
            }
        }
        function loadModules(modulesToLoad) {
            var runBlocks = [];
            forEach(modulesToLoad,
            function(module) {
                if (loadedModules.get(module)) return;
                loadedModules.put(module, true);
                try {
                    if (isString(module)) {
                        var moduleFn = angularModule(module);
                        runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
                        for (var invokeQueue = moduleFn._invokeQueue,
                        i = 0,
                        ii = invokeQueue.length; i < ii; i++) {
                            var invokeArgs = invokeQueue[i],
                            provider = providerInjector.get(invokeArgs[0]);
                            provider[invokeArgs[1]].apply(provider, invokeArgs[2])
                        }
                    } else if (isFunction(module)) {
                        runBlocks.push(providerInjector.invoke(module))
                    } else if (isArray(module)) {
                        runBlocks.push(providerInjector.invoke(module))
                    } else {
                        assertArgFn(module, "module")
                    }
                } catch(e) {
                    if (isArray(module)) {
                        module = module[module.length - 1]
                    }
                    if (e.message && e.stack && e.stack.indexOf(e.message) == -1) {
                        e = e.message + "\n" + e.stack
                    }
                    throw $injectorMinErr("modulerr", "Failed to instantiate module {0} due to:\n{1}", module, e.stack || e.message || e)
                }
            });
            return runBlocks
        }
        function createInternalInjector(cache, factory) {
            function getService(serviceName) {
                if (cache.hasOwnProperty(serviceName)) {
                    if (cache[serviceName] === INSTANTIATING) {
                        throw $injectorMinErr("cdep", "Circular dependency found: {0}", path.join(" <- "))
                    }
                    return cache[serviceName]
                } else {
                    try {
                        path.unshift(serviceName);
                        cache[serviceName] = INSTANTIATING;
                        return cache[serviceName] = factory(serviceName)
                    } finally {
                        path.shift()
                    }
                }
            }
            function invoke(fn, self, locals) {
                var args = [],
                $inject = annotate(fn),
                length,
                i,
                key;
                for (i = 0, length = $inject.length; i < length; i++) {
                    key = $inject[i];
                    if (typeof key !== "string") {
                        throw $injectorMinErr("itkn", "Incorrect injection token! Expected service name as string, got {0}", key)
                    }
                    args.push(locals && locals.hasOwnProperty(key) ? locals[key] : getService(key))
                }
                if (!fn.$inject) {
                    fn = fn[length]
                }
                switch (self ? -1 : args.length) {
                case 0:
                    return fn();
                case 1:
                    return fn(args[0]);
                case 2:
                    return fn(args[0], args[1]);
                case 3:
                    return fn(args[0], args[1], args[2]);
                case 4:
                    return fn(args[0], args[1], args[2], args[3]);
                case 5:
                    return fn(args[0], args[1], args[2], args[3], args[4]);
                case 6:
                    return fn(args[0], args[1], args[2], args[3], args[4], args[5]);
                case 7:
                    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
                case 8:
                    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
                case 9:
                    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
                case 10:
                    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
                default:
                    return fn.apply(self, args)
                }
            }
            function instantiate(Type, locals) {
                var Constructor = function() {},
                instance,
                returnedValue;
                Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype;
                instance = new Constructor;
                returnedValue = invoke(Type, instance, locals);
                return isObject(returnedValue) ? returnedValue: instance
            }
            return {
                invoke: invoke,
                instantiate: instantiate,
                get: getService,
                annotate: annotate,
                has: function(name) {
                    return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name)
                }
            }
        }
    }
    function $AnchorScrollProvider() {
        var autoScrollingEnabled = true;
        this.disableAutoScrolling = function() {
            autoScrollingEnabled = false
        };
        this.$get = ["$window", "$location", "$rootScope",
        function($window, $location, $rootScope) {
            var document = $window.document;
            function getFirstAnchor(list) {
                var result = null;
                forEach(list,
                function(element) {
                    if (!result && lowercase(element.nodeName) === "a") result = element
                });
                return result
            }
            function scroll() {
                var hash = $location.hash(),
                elm;
                if (!hash) $window.scrollTo(0, 0);
                else if (elm = document.getElementById(hash)) elm.scrollIntoView();
                else if (elm = getFirstAnchor(document.getElementsByName(hash))) elm.scrollIntoView();
                else if (hash === "top") $window.scrollTo(0, 0)
            }
            if (autoScrollingEnabled) {
                $rootScope.$watch(function autoScrollWatch() {
                    return $location.hash()
                },
                function autoScrollWatchAction() {
                    $rootScope.$evalAsync(scroll)
                })
            }
            return scroll
        }]
    }
    var $animateMinErr = minErr("$animate");
    var $AnimateProvider = ["$provide",
    function($provide) {
        this.$$selectors = {};
        this.register = function(name, factory) {
            var key = name + "-animation";
            if (name && name.charAt(0) != ".") throw $animateMinErr("notcsel", "Expecting class selector starting with '.' got '{0}'.", name);
            this.$$selectors[name.substr(1)] = key;
            $provide.factory(key, factory)
        };
        this.$get = ["$timeout",
        function($timeout) {
            return {
                enter: function(element, parent, after, done) {
                    var afterNode = after && after[after.length - 1];
                    var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
                    var afterNextSibling = afterNode && afterNode.nextSibling || null;
                    forEach(element,
                    function(node) {
                        parentNode.insertBefore(node, afterNextSibling)
                    });
                    done && $timeout(done, 0, false)
                },
                leave: function(element, done) {
                    element.remove();
                    done && $timeout(done, 0, false)
                },
                move: function(element, parent, after, done) {
                    this.enter(element, parent, after, done)
                },
                addClass: function(element, className, done) {
                    className = isString(className) ? className: isArray(className) ? className.join(" ") : "";
                    forEach(element,
                    function(element) {
                        JQLiteAddClass(element, className)
                    });
                    done && $timeout(done, 0, false)
                },
                removeClass: function(element, className, done) {
                    className = isString(className) ? className: isArray(className) ? className.join(" ") : "";
                    forEach(element,
                    function(element) {
                        JQLiteRemoveClass(element, className)
                    });
                    done && $timeout(done, 0, false)
                },
                enabled: noop
            }
        }]
    }];
    function Browser(window, document, $log, $sniffer) {
        var self = this,
        rawDocument = document[0],
        location = window.location,
        history = window.history,
        setTimeout = window.setTimeout,
        clearTimeout = window.clearTimeout,
        pendingDeferIds = {};
        self.isMock = false;
        var outstandingRequestCount = 0;
        var outstandingRequestCallbacks = [];
        self.$$completeOutstandingRequest = completeOutstandingRequest;
        self.$$incOutstandingRequestCount = function() {
            outstandingRequestCount++
        };
        function completeOutstandingRequest(fn) {
            try {
                fn.apply(null, sliceArgs(arguments, 1))
            } finally {
                outstandingRequestCount--;
                if (outstandingRequestCount === 0) {
                    while (outstandingRequestCallbacks.length) {
                        try {
                            outstandingRequestCallbacks.pop()()
                        } catch(e) {
                            $log.error(e)
                        }
                    }
                }
            }
        }
        self.notifyWhenNoOutstandingRequests = function(callback) {
            forEach(pollFns,
            function(pollFn) {
                pollFn()
            });
            if (outstandingRequestCount === 0) {
                callback()
            } else {
                outstandingRequestCallbacks.push(callback)
            }
        };
        var pollFns = [],
        pollTimeout;
        self.addPollFn = function(fn) {
            if (isUndefined(pollTimeout)) startPoller(100, setTimeout);
            pollFns.push(fn);
            return fn
        };
        function startPoller(interval, setTimeout) { (function check() {
                forEach(pollFns,
                function(pollFn) {
                    pollFn()
                });
                pollTimeout = setTimeout(check, interval)
            })()
        }
        var lastBrowserUrl = location.href,
        baseElement = document.find("base"),
        newLocation = null;
        self.url = function(url, replace) {
            if (location !== window.location) location = window.location;
            if (url) {
                if (lastBrowserUrl == url) return;
                lastBrowserUrl = url;
                if ($sniffer.history) {
                    if (replace) history.replaceState(null, "", url);
                    else {
                        history.pushState(null, "", url);
                        baseElement.attr("href", baseElement.attr("href"))
                    }
                } else {
                    newLocation = url;
                    if (replace) {
                        location.replace(url)
                    } else {
                        location.href = url
                    }
                }
                return self
            } else {
                return newLocation || location.href.replace(/%27/g, "'")
            }
        };
        var urlChangeListeners = [],
        urlChangeInit = false;
        function fireUrlChange() {
            newLocation = null;
            if (lastBrowserUrl == self.url()) return;
            lastBrowserUrl = self.url();
            forEach(urlChangeListeners,
            function(listener) {
                listener(self.url())
            })
        }
        self.onUrlChange = function(callback) {
            if (!urlChangeInit) {
                if ($sniffer.history) jqLite(window).on("popstate", fireUrlChange);
                if ($sniffer.hashchange) jqLite(window).on("hashchange", fireUrlChange);
                else self.addPollFn(fireUrlChange);
                urlChangeInit = true
            }
            urlChangeListeners.push(callback);
            return callback
        };
        self.baseHref = function() {
            var href = baseElement.attr("href");
            return href ? href.replace(/^https?\:\/\/[^\/]*/, "") : ""
        };
        var lastCookies = {};
        var lastCookieString = "";
        var cookiePath = self.baseHref();
        self.cookies = function(name, value) {
            var cookieLength, cookieArray, cookie, i, index;
            if (name) {
                if (value === undefined) {
                    rawDocument.cookie = escape(name) + "=;path=" + cookiePath + ";expires=Thu, 01 Jan 1970 00:00:00 GMT"
                } else {
                    if (isString(value)) {
                        cookieLength = (rawDocument.cookie = escape(name) + "=" + escape(value) + ";path=" + cookiePath).length + 1;
                        if (cookieLength > 4096) {
                            $log.warn("Cookie '" + name + "' possibly not set or overflowed because it was too large (" + cookieLength + " > 4096 bytes)!")
                        }
                    }
                }
            } else {
                if (rawDocument.cookie !== lastCookieString) {
                    lastCookieString = rawDocument.cookie;
                    cookieArray = lastCookieString.split("; ");
                    lastCookies = {};
                    for (i = 0; i < cookieArray.length; i++) {
                        cookie = cookieArray[i];
                        index = cookie.indexOf("=");
                        if (index > 0) {
                            var name = unescape(cookie.substring(0, index));
                            if (lastCookies[name] === undefined) {
                                lastCookies[name] = unescape(cookie.substring(index + 1))
                            }
                        }
                    }
                }
                return lastCookies
            }
        };
        self.defer = function(fn, delay) {
            var timeoutId;
            outstandingRequestCount++;
            timeoutId = setTimeout(function() {
                delete pendingDeferIds[timeoutId];
                completeOutstandingRequest(fn)
            },
            delay || 0);
            pendingDeferIds[timeoutId] = true;
            return timeoutId
        };
        self.defer.cancel = function(deferId) {
            if (pendingDeferIds[deferId]) {
                delete pendingDeferIds[deferId];
                clearTimeout(deferId);
                completeOutstandingRequest(noop);
                return true
            }
            return false
        }
    }
    function $BrowserProvider() {
        this.$get = ["$window", "$log", "$sniffer", "$document",
        function($window, $log, $sniffer, $document) {
            return new Browser($window, $document, $log, $sniffer)
        }]
    }
    function $CacheFactoryProvider() {
        this.$get = function() {
            var caches = {};
            function cacheFactory(cacheId, options) {
                if (cacheId in caches) {
                    throw minErr("$cacheFactory")("iid", "CacheId '{0}' is already taken!", cacheId)
                }
                var size = 0,
                stats = extend({},
                options, {
                    id: cacheId
                }),
                data = {},
                capacity = options && options.capacity || Number.MAX_VALUE,
                lruHash = {},
                freshEnd = null,
                staleEnd = null;
                return caches[cacheId] = {
                    put: function(key, value) {
                        var lruEntry = lruHash[key] || (lruHash[key] = {
                            key: key
                        });
                        refresh(lruEntry);
                        if (isUndefined(value)) return;
                        if (! (key in data)) size++;
                        data[key] = value;
                        if (size > capacity) {
                            this.remove(staleEnd.key)
                        }
                        return value
                    },
                    get: function(key) {
                        var lruEntry = lruHash[key];
                        if (!lruEntry) return;
                        refresh(lruEntry);
                        return data[key]
                    },
                    remove: function(key) {
                        var lruEntry = lruHash[key];
                        if (!lruEntry) return;
                        if (lruEntry == freshEnd) freshEnd = lruEntry.p;
                        if (lruEntry == staleEnd) staleEnd = lruEntry.n;
                        link(lruEntry.n, lruEntry.p);
                        delete lruHash[key];
                        delete data[key];
                        size--
                    },
                    removeAll: function() {
                        data = {};
                        size = 0;
                        lruHash = {};
                        freshEnd = staleEnd = null
                    },
                    destroy: function() {
                        data = null;
                        stats = null;
                        lruHash = null;
                        delete caches[cacheId]
                    },
                    info: function() {
                        return extend({},
                        stats, {
                            size: size
                        })
                    }
                };
                function refresh(entry) {
                    if (entry != freshEnd) {
                        if (!staleEnd) {
                            staleEnd = entry
                        } else if (staleEnd == entry) {
                            staleEnd = entry.n
                        }
                        link(entry.n, entry.p);
                        link(entry, freshEnd);
                        freshEnd = entry;
                        freshEnd.n = null
                    }
                }
                function link(nextEntry, prevEntry) {
                    if (nextEntry != prevEntry) {
                        if (nextEntry) nextEntry.p = prevEntry;
                        if (prevEntry) prevEntry.n = nextEntry
                    }
                }
            }
            cacheFactory.info = function() {
                var info = {};
                forEach(caches,
                function(cache, cacheId) {
                    info[cacheId] = cache.info()
                });
                return info
            };
            cacheFactory.get = function(cacheId) {
                return caches[cacheId]
            };
            return cacheFactory
        }
    }
    function $TemplateCacheProvider() {
        this.$get = ["$cacheFactory",
        function($cacheFactory) {
            return $cacheFactory("templates")
        }]
    }
    var $compileMinErr = minErr("$compile");
    $CompileProvider.$inject = ["$provide"];
    function $CompileProvider($provide) {
        var hasDirectives = {},
        Suffix = "Directive",
        COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
        CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
        aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
        imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;
        var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
        this.directive = function registerDirective(name, directiveFactory) {
            assertNotHasOwnProperty(name, "directive");
            if (isString(name)) {
                assertArg(directiveFactory, "directiveFactory");
                if (!hasDirectives.hasOwnProperty(name)) {
                    hasDirectives[name] = [];
                    $provide.factory(name + Suffix, ["$injector", "$exceptionHandler",
                    function($injector, $exceptionHandler) {
                        var directives = [];
                        forEach(hasDirectives[name],
                        function(directiveFactory, index) {
                            try {
                                var directive = $injector.invoke(directiveFactory);
                                if (isFunction(directive)) {
                                    directive = {
                                        compile: valueFn(directive)
                                    }
                                } else if (!directive.compile && directive.link) {
                                    directive.compile = valueFn(directive.link)
                                }
                                directive.priority = directive.priority || 0;
                                directive.index = index;
                                directive.name = directive.name || name;
                                directive.require = directive.require || directive.controller && directive.name;
                                directive.restrict = directive.restrict || "A";
                                directives.push(directive)
                            } catch(e) {
                                $exceptionHandler(e)
                            }
                        });
                        return directives
                    }])
                }
                hasDirectives[name].push(directiveFactory)
            } else {
                forEach(name, reverseParams(registerDirective))
            }
            return this
        };
        this.aHrefSanitizationWhitelist = function(regexp) {
            if (isDefined(regexp)) {
                aHrefSanitizationWhitelist = regexp;
                return this
            }
            return aHrefSanitizationWhitelist
        };
        this.imgSrcSanitizationWhitelist = function(regexp) {
            if (isDefined(regexp)) {
                imgSrcSanitizationWhitelist = regexp;
                return this
            }
            return imgSrcSanitizationWhitelist
        };
        this.$get = ["$injector", "$interpolate", "$exceptionHandler", "$http", "$templateCache", "$parse", "$controller", "$rootScope", "$document", "$sce", "$animate",
        function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse, $controller, $rootScope, $document, $sce, $animate) {
            var Attributes = function(element, attr) {
                this.$$element = element;
                this.$attr = attr || {}
            };
            Attributes.prototype = {
                $normalize: directiveNormalize,
                $addClass: function(classVal) {
                    if (classVal && classVal.length > 0) {
                        $animate.addClass(this.$$element, classVal)
                    }
                },
                $removeClass: function(classVal) {
                    if (classVal && classVal.length > 0) {
                        $animate.removeClass(this.$$element, classVal)
                    }
                },
                $set: function(key, value, writeAttr, attrName) {
                    if (key == "class") {
                        value = value || "";
                        var current = this.$$element.attr("class") || "";
                        this.$removeClass(tokenDifference(current, value).join(" "));
                        this.$addClass(tokenDifference(value, current).join(" "))
                    } else {
                        var booleanKey = getBooleanAttrName(this.$$element[0], key),
                        normalizedVal,
                        nodeName;
                        if (booleanKey) {
                            this.$$element.prop(key, value);
                            attrName = booleanKey
                        }
                        this[key] = value;
                        if (attrName) {
                            this.$attr[key] = attrName
                        } else {
                            attrName = this.$attr[key];
                            if (!attrName) {
                                this.$attr[key] = attrName = snake_case(key, "-")
                            }
                        }
                        nodeName = nodeName_(this.$$element);
                        if (nodeName === "A" && key === "href" || nodeName === "IMG" && key === "src") {
                            if (!msie || msie >= 8) {
                                normalizedVal = urlResolve(value).href;
                                if (normalizedVal !== "") {
                                    if (key === "href" && !normalizedVal.match(aHrefSanitizationWhitelist) || key === "src" && !normalizedVal.match(imgSrcSanitizationWhitelist)) {
                                        this[key] = value = "unsafe:" + normalizedVal
                                    }
                                }
                            }
                        }
                        if (writeAttr !== false) {
                            if (value === null || value === undefined) {
                                this.$$element.removeAttr(attrName)
                            } else {
                                this.$$element.attr(attrName, value)
                            }
                        }
                    }
                    var $$observers = this.$$observers;
                    $$observers && forEach($$observers[key],
                    function(fn) {
                        try {
                            fn(value)
                        } catch(e) {
                            $exceptionHandler(e)
                        }
                    });
                    function tokenDifference(str1, str2) {
                        var values = [],
                        tokens1 = str1.split(/\s+/),
                        tokens2 = str2.split(/\s+/);
                        outer: for (var i = 0; i < tokens1.length; i++) {
                            var token = tokens1[i];
                            for (var j = 0; j < tokens2.length; j++) {
                                if (token == tokens2[j]) continue outer
                            }
                            values.push(token)
                        }
                        return values
                    }
                },
                $observe: function(key, fn) {
                    var attrs = this,
                    $$observers = attrs.$$observers || (attrs.$$observers = {}),
                    listeners = $$observers[key] || ($$observers[key] = []);
                    listeners.push(fn);
                    $rootScope.$evalAsync(function() {
                        if (!listeners.$$inter) {
                            fn(attrs[key])
                        }
                    });
                    return fn
                }
            };
            var startSymbol = $interpolate.startSymbol(),
            endSymbol = $interpolate.endSymbol(),
            denormalizeTemplate = startSymbol == "{{" || endSymbol == "}}" ? identity: function denormalizeTemplate(template) {
                return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol)
            },
            NG_ATTR_BINDING = /^ngAttr[A-Z]/;
            return compile;
            function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {
                if (! ($compileNodes instanceof jqLite)) {
                    $compileNodes = jqLite($compileNodes)
                }
                forEach($compileNodes,
                function(node, index) {
                    if (node.nodeType == 3 && node.nodeValue.match(/\S+/)) {
                        $compileNodes[index] = node = jqLite(node).wrap("<span></span>").parent()[0]
                    }
                });
                var compositeLinkFn = compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext);
                return function publicLinkFn(scope, cloneConnectFn) {
                    assertArg(scope, "scope");
                    var $linkNode = cloneConnectFn ? JQLitePrototype.clone.call($compileNodes) : $compileNodes;
                    for (var i = 0,
                    ii = $linkNode.length; i < ii; i++) {
                        var node = $linkNode[i];
                        if (node.nodeType == 1 || node.nodeType == 9) {
                            $linkNode.eq(i).data("$scope", scope)
                        }
                    }
                    safeAddClass($linkNode, "ng-scope");
                    if (cloneConnectFn) cloneConnectFn($linkNode, scope);
                    if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode);
                    return $linkNode
                }
            }
            function safeAddClass($element, className) {
                try {
                    $element.addClass(className)
                } catch(e) {}
            }
            function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective, previousCompileContext) {
                var linkFns = [],
                nodeLinkFn,
                childLinkFn,
                directives,
                attrs,
                linkFnFound;
                for (var i = 0; i < nodeList.length; i++) {
                    attrs = new Attributes;
                    directives = collectDirectives(nodeList[i], [], attrs, i == 0 ? maxPriority: undefined, ignoreDirective);
                    nodeLinkFn = directives.length ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement, null, [], [], previousCompileContext) : null;
                    childLinkFn = nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes || !nodeList[i].childNodes.length ? null: compileNodes(nodeList[i].childNodes, nodeLinkFn ? nodeLinkFn.transclude: transcludeFn);
                    linkFns.push(nodeLinkFn);
                    linkFns.push(childLinkFn);
                    linkFnFound = linkFnFound || nodeLinkFn || childLinkFn;
                    previousCompileContext = null
                }
                return linkFnFound ? compositeLinkFn: null;
                function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) {
                    var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn, i, ii, n;
                    var stableNodeList = [];
                    for (i = 0, ii = nodeList.length; i < ii; i++) {
                        stableNodeList.push(nodeList[i])
                    }
                    for (i = 0, n = 0, ii = linkFns.length; i < ii; n++) {
                        node = stableNodeList[n];
                        nodeLinkFn = linkFns[i++];
                        childLinkFn = linkFns[i++];
                        if (nodeLinkFn) {
                            if (nodeLinkFn.scope) {
                                childScope = scope.$new(isObject(nodeLinkFn.scope));
                                jqLite(node).data("$scope", childScope)
                            } else {
                                childScope = scope
                            }
                            childTranscludeFn = nodeLinkFn.transclude;
                            if (childTranscludeFn || !boundTranscludeFn && transcludeFn) {
                                nodeLinkFn(childLinkFn, childScope, node, $rootElement,
                                function(transcludeFn) {
                                    return function(cloneFn) {
                                        var transcludeScope = scope.$new();
                                        transcludeScope.$$transcluded = true;
                                        return transcludeFn(transcludeScope, cloneFn).on("$destroy", bind(transcludeScope, transcludeScope.$destroy))
                                    }
                                } (childTranscludeFn || transcludeFn))
                            } else {
                                nodeLinkFn(childLinkFn, childScope, node, undefined, boundTranscludeFn)
                            }
                        } else if (childLinkFn) {
                            childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn)
                        }
                    }
                }
            }
            function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
                var nodeType = node.nodeType,
                attrsMap = attrs.$attr,
                match, className;
                switch (nodeType) {
                case 1:
                    addDirective(directives, directiveNormalize(nodeName_(node).toLowerCase()), "E", maxPriority, ignoreDirective);
                    for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes,
                    j = 0,
                    jj = nAttrs && nAttrs.length; j < jj; j++) {
                        var attrStartName = false;
                        var attrEndName = false;
                        attr = nAttrs[j];
                        if (!msie || msie >= 8 || attr.specified) {
                            name = attr.name;
                            ngAttrName = directiveNormalize(name);
                            if (NG_ATTR_BINDING.test(ngAttrName)) {
                                name = snake_case(ngAttrName.substr(6), "-")
                            }
                            var directiveNName = ngAttrName.replace(/(Start|End)$/, "");
                            if (ngAttrName === directiveNName + "Start") {
                                attrStartName = name;
                                attrEndName = name.substr(0, name.length - 5) + "end";
                                name = name.substr(0, name.length - 6)
                            }
                            nName = directiveNormalize(name.toLowerCase());
                            attrsMap[nName] = name;
                            attrs[nName] = value = trim(msie && name == "href" ? decodeURIComponent(node.getAttribute(name, 2)) : attr.value);
                            if (getBooleanAttrName(node, nName)) {
                                attrs[nName] = true
                            }
                            addAttrInterpolateDirective(node, directives, value, nName);
                            addDirective(directives, nName, "A", maxPriority, ignoreDirective, attrStartName, attrEndName)
                        }
                    }
                    className = node.className;
                    if (isString(className) && className !== "") {
                        while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) {
                            nName = directiveNormalize(match[2]);
                            if (addDirective(directives, nName, "C", maxPriority, ignoreDirective)) {
                                attrs[nName] = trim(match[3])
                            }
                            className = className.substr(match.index + match[0].length)
                        }
                    }
                    break;
                case 3:
                    addTextInterpolateDirective(directives, node.nodeValue);
                    break;
                case 8:
                    try {
                        match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);
                        if (match) {
                            nName = directiveNormalize(match[1]);
                            if (addDirective(directives, nName, "M", maxPriority, ignoreDirective)) {
                                attrs[nName] = trim(match[2])
                            }
                        }
                    } catch(e) {}
                    break
                }
                directives.sort(byPriority);
                return directives
            }
            function groupScan(node, attrStart, attrEnd) {
                var nodes = [];
                var depth = 0;
                if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
                    var startNode = node;
                    do {
                        if (!node) {
                            throw $compileMinErr("uterdir", "Unterminated attribute, found '{0}' but no matching '{1}' found.", attrStart, attrEnd)
                        }
                        if (node.nodeType == 1) {
                            if (node.hasAttribute(attrStart)) depth++;
                            if (node.hasAttribute(attrEnd)) depth--
                        }
                        nodes.push(node);
                        node = node.nextSibling
                    } while ( depth > 0 )
                } else {
                    nodes.push(node)
                }
                return jqLite(nodes)
            }
            function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
                return function(scope, element, attrs, controllers) {
                    element = groupScan(element[0], attrStart, attrEnd);
                    return linkFn(scope, element, attrs, controllers)
                }
            }
            function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection, originalReplaceDirective, preLinkFns, postLinkFns, previousCompileContext) {
                previousCompileContext = previousCompileContext || {};
                var terminalPriority = -Number.MAX_VALUE,
                newScopeDirective, newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
                templateDirective = previousCompileContext.templateDirective,
                $compileNode = templateAttrs.$$element = jqLite(compileNode),
                directive,
                directiveName,
                $template,
                transcludeDirective = previousCompileContext.transcludeDirective,
                replaceDirective = originalReplaceDirective,
                childTranscludeFn = transcludeFn,
                controllerDirectives,
                linkFn,
                directiveValue;
                for (var i = 0,
                ii = directives.length; i < ii; i++) {
                    directive = directives[i];
                    var attrStart = directive.$$start;
                    var attrEnd = directive.$$end;
                    if (attrStart) {
                        $compileNode = groupScan(compileNode, attrStart, attrEnd)
                    }
                    $template = undefined;
                    if (terminalPriority > directive.priority) {
                        break
                    }
                    if (directiveValue = directive.scope) {
                        newScopeDirective = newScopeDirective || directive;
                        if (!directive.templateUrl) {
                            assertNoDuplicate("new/isolated scope", newIsolateScopeDirective, directive, $compileNode);
                            if (isObject(directiveValue)) {
                                safeAddClass($compileNode, "ng-isolate-scope");
                                newIsolateScopeDirective = directive
                            }
                            safeAddClass($compileNode, "ng-scope")
                        }
                    }
                    directiveName = directive.name;
                    if (!directive.templateUrl && directive.controller) {
                        directiveValue = directive.controller;
                        controllerDirectives = controllerDirectives || {};
                        assertNoDuplicate("'" + directiveName + "' controller", controllerDirectives[directiveName], directive, $compileNode);
                        controllerDirectives[directiveName] = directive
                    }
                    if (directiveValue = directive.transclude) {
                        if (directiveName !== "ngRepeat") {
                            assertNoDuplicate("transclusion", transcludeDirective, directive, $compileNode);
                            transcludeDirective = directive
                        }
                        if (directiveValue == "element") {
                            terminalPriority = directive.priority;
                            $template = groupScan(compileNode, attrStart, attrEnd);
                            $compileNode = templateAttrs.$$element = jqLite(document.createComment(" " + directiveName + ": " + templateAttrs[directiveName] + " "));
                            compileNode = $compileNode[0];
                            replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode);
                            childTranscludeFn = compile($template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, {
                                newIsolateScopeDirective: newIsolateScopeDirective,
                                transcludeDirective: transcludeDirective,
                                templateDirective: templateDirective
                            })
                        } else {
                            $template = jqLite(JQLiteClone(compileNode)).contents();
                            $compileNode.html("");
                            childTranscludeFn = compile($template, transcludeFn)
                        }
                    }
                    if (directive.template) {
                        assertNoDuplicate("template", templateDirective, directive, $compileNode);
                        templateDirective = directive;
                        directiveValue = isFunction(directive.template) ? directive.template($compileNode, templateAttrs) : directive.template;
                        directiveValue = denormalizeTemplate(directiveValue);
                        if (directive.replace) {
                            replaceDirective = directive;
                            $template = jqLite("<div>" + trim(directiveValue) + "</div>").contents();
                            compileNode = $template[0];
                            if ($template.length != 1 || compileNode.nodeType !== 1) {
                                throw $compileMinErr("tplrt", "Template for directive '{0}' must have exactly one root element. {1}", directiveName, "")
                            }
                            replaceWith(jqCollection, $compileNode, compileNode);
                            var newTemplateAttrs = {
                                $attr: {}
                            };
                            directives = directives.concat(collectDirectives(compileNode, directives.splice(i + 1, directives.length - (i + 1)), newTemplateAttrs));
                            mergeTemplateAttributes(templateAttrs, newTemplateAttrs);
                            ii = directives.length
                        } else {
                            $compileNode.html(directiveValue)
                        }
                    }
                    if (directive.templateUrl) {
                        assertNoDuplicate("template", templateDirective, directive, $compileNode);
                        templateDirective = directive;
                        if (directive.replace) {
                            replaceDirective = directive
                        }
                        nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, {
                            newIsolateScopeDirective: newIsolateScopeDirective,
                            transcludeDirective: transcludeDirective,
                            templateDirective: templateDirective
                        });
                        ii = directives.length
                    } else if (directive.compile) {
                        try {
                            linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);
                            if (isFunction(linkFn)) {
                                addLinkFns(null, linkFn, attrStart, attrEnd)
                            } else if (linkFn) {
                                addLinkFns(linkFn.pre, linkFn.post, attrStart, attrEnd)
                            }
                        } catch(e) {
                            $exceptionHandler(e, startingTag($compileNode))
                        }
                    }
                    if (directive.terminal) {
                        nodeLinkFn.terminal = true;
                        terminalPriority = Math.max(terminalPriority, directive.priority)
                    }
                }
                nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope;
                nodeLinkFn.transclude = transcludeDirective && childTranscludeFn;
                return nodeLinkFn;
                function addLinkFns(pre, post, attrStart, attrEnd) {
                    if (pre) {
                        if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
                        pre.require = directive.require;
                        preLinkFns.push(pre)
                    }
                    if (post) {
                        if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
                        post.require = directive.require;
                        postLinkFns.push(post)
                    }
                }
                function getControllers(require, $element) {
                    var value, retrievalMethod = "data",
                    optional = false;
                    if (isString(require)) {
                        while ((value = require.charAt(0)) == "^" || value == "?") {
                            require = require.substr(1);
                            if (value == "^") {
                                retrievalMethod = "inheritedData"
                            }
                            optional = optional || value == "?"
                        }
                        value = $element[retrievalMethod]("$" + require + "Controller");
                        if ($element[0].nodeType == 8 && $element[0].$$controller) {
                            value = value || $element[0].$$controller;
                            $element[0].$$controller = null
                        }
                        if (!value && !optional) {
                            throw $compileMinErr("ctreq", "Controller '{0}', required by directive '{1}', can't be found!", require, directiveName)
                        }
                        return value
                    } else if (isArray(require)) {
                        value = [];
                        forEach(require,
                        function(require) {
                            value.push(getControllers(require, $element))
                        })
                    }
                    return value
                }
                function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
                    var attrs, $element, i, ii, linkFn, controller;
                    if (compileNode === linkNode) {
                        attrs = templateAttrs
                    } else {
                        attrs = shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr))
                    }
                    $element = attrs.$$element;
                    if (newIsolateScopeDirective) {
                        var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
                        var parentScope = scope.$parent || scope;
                        forEach(newIsolateScopeDirective.scope,
                        function(definition, scopeName) {
                            var match = definition.match(LOCAL_REGEXP) || [],
                            attrName = match[3] || scopeName,
                            optional = match[2] == "?",
                            mode = match[1],
                            lastValue,
                            parentGet,
                            parentSet;
                            scope.$$isolateBindings[scopeName] = mode + attrName;
                            switch (mode) {
                            case "@":
                                {
                                    attrs.$observe(attrName,
                                    function(value) {
                                        scope[scopeName] = value
                                    });
                                    attrs.$$observers[attrName].$$scope = parentScope;
                                    if (attrs[attrName]) {
                                        scope[scopeName] = $interpolate(attrs[attrName])(parentScope)
                                    }
                                    break
                                }
                            case "=":
                                {
                                    if (optional && !attrs[attrName]) {
                                        return
                                    }
                                    parentGet = $parse(attrs[attrName]);
                                    parentSet = parentGet.assign ||
                                    function() {
                                        lastValue = scope[scopeName] = parentGet(parentScope);
                                        throw $compileMinErr("nonassign", "Expression '{0}' used with directive '{1}' is non-assignable!", attrs[attrName], newIsolateScopeDirective.name)
                                    };
                                    lastValue = scope[scopeName] = parentGet(parentScope);
                                    scope.$watch(function parentValueWatch() {
                                        var parentValue = parentGet(parentScope);
                                        if (parentValue !== scope[scopeName]) {
                                            if (parentValue !== lastValue) {
                                                lastValue = scope[scopeName] = parentValue
                                            } else {
                                                parentSet(parentScope, parentValue = lastValue = scope[scopeName])
                                            }
                                        }
                                        return parentValue
                                    });
                                    break
                                }
                            case "&":
                                {
                                    parentGet = $parse(attrs[attrName]);
                                    scope[scopeName] = function(locals) {
                                        return parentGet(parentScope, locals)
                                    };
                                    break
                                }
                            default:
                                {
                                    throw $compileMinErr("iscp", "Invalid isolate scope definition for directive '{0}'. Definition: {... {1}: '{2}' ...}", newIsolateScopeDirective.name, scopeName, definition)
                                }
                            }
                        })
                    }
                    if (controllerDirectives) {
                        forEach(controllerDirectives,
                        function(directive) {
                            var locals = {
                                $scope: scope,
                                $element: $element,
                                $attrs: attrs,
                                $transclude: boundTranscludeFn
                            },
                            controllerInstance;
                            controller = directive.controller;
                            if (controller == "@") {
                                controller = attrs[directive.name]
                            }
                            controllerInstance = $controller(controller, locals);
                            if ($element[0].nodeType == 8) {
                                $element[0].$$controller = controllerInstance
                            } else {
                                $element.data("$" + directive.name + "Controller", controllerInstance)
                            }
                            if (directive.controllerAs) {
                                locals.$scope[directive.controllerAs] = controllerInstance
                            }
                        })
                    }
                    for (i = 0, ii = preLinkFns.length; i < ii; i++) {
                        try {
                            linkFn = preLinkFns[i];
                            linkFn(scope, $element, attrs, linkFn.require && getControllers(linkFn.require, $element))
                        } catch(e) {
                            $exceptionHandler(e, startingTag($element))
                        }
                    }
                    childLinkFn && childLinkFn(scope, linkNode.childNodes, undefined, boundTranscludeFn);
                    for (i = postLinkFns.length - 1; i >= 0; i--) {
                        try {
                            linkFn = postLinkFns[i];
                            linkFn(scope, $element, attrs, linkFn.require && getControllers(linkFn.require, $element))
                        } catch(e) {
                            $exceptionHandler(e, startingTag($element))
                        }
                    }
                }
            }
            function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName, endAttrName) {
                if (name === ignoreDirective) return null;
                var match = null;
                if (hasDirectives.hasOwnProperty(name)) {
                    for (var directive, directives = $injector.get(name + Suffix), i = 0, ii = directives.length; i < ii; i++) {
                        try {
                            directive = directives[i];
                            if ((maxPriority === undefined || maxPriority > directive.priority) && directive.restrict.indexOf(location) != -1) {
                                if (startAttrName) {
                                    directive = inherit(directive, {
                                        $$start: startAttrName,
                                        $$end: endAttrName
                                    })
                                }
                                tDirectives.push(directive);
                                match = directive
                            }
                        } catch(e) {
                            $exceptionHandler(e)
                        }
                    }
                }
                return match
            }
            function mergeTemplateAttributes(dst, src) {
                var srcAttr = src.$attr,
                dstAttr = dst.$attr,
                $element = dst.$$element;
                forEach(dst,
                function(value, key) {
                    if (key.charAt(0) != "$") {
                        if (src[key]) {
                            value += (key === "style" ? ";": " ") + src[key]
                        }
                        dst.$set(key, value, true, srcAttr[key])
                    }
                });
                forEach(src,
                function(value, key) {
                    if (key == "class") {
                        safeAddClass($element, value);
                        dst["class"] = (dst["class"] ? dst["class"] + " ": "") + value
                    } else if (key == "style") {
                        $element.attr("style", $element.attr("style") + ";" + value)
                    } else if (key.charAt(0) != "$" && !dst.hasOwnProperty(key)) {
                        dst[key] = value;
                        dstAttr[key] = srcAttr[key]
                    }
                })
            }
            function compileTemplateUrl(directives, $compileNode, tAttrs, $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {
                var linkQueue = [],
                afterTemplateNodeLinkFn,
                afterTemplateChildLinkFn,
                beforeTemplateCompileNode = $compileNode[0],
                origAsyncDirective = directives.shift(),
                derivedSyncDirective = extend({},
                origAsyncDirective, {
                    templateUrl: null,
                    transclude: null,
                    replace: null
                }),
                templateUrl = isFunction(origAsyncDirective.templateUrl) ? origAsyncDirective.templateUrl($compileNode, tAttrs) : origAsyncDirective.templateUrl;
                $compileNode.html("");
                $http.get($sce.getTrustedResourceUrl(templateUrl), {
                    cache: $templateCache
                }).success(function(content) {
                    var compileNode, tempTemplateAttrs, $template;
                    content = denormalizeTemplate(content);
                    if (origAsyncDirective.replace) {
                        $template = jqLite("<div>" + trim(content) + "</div>").contents();
                        compileNode = $template[0];
                        if ($template.length != 1 || compileNode.nodeType !== 1) {
                            throw $compileMinErr("tplrt", "Template for directive '{0}' must have exactly one root element. {1}", origAsyncDirective.name, templateUrl)
                        }
                        tempTemplateAttrs = {
                            $attr: {}
                        };
                        replaceWith($rootElement, $compileNode, compileNode);
                        collectDirectives(compileNode, directives, tempTemplateAttrs);
                        mergeTemplateAttributes(tAttrs, tempTemplateAttrs)
                    } else {
                        compileNode = beforeTemplateCompileNode;
                        $compileNode.html(content)
                    }
                    directives.unshift(derivedSyncDirective);
                    afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns, previousCompileContext);
                    forEach($rootElement,
                    function(node, i) {
                        if (node == compileNode) {
                            $rootElement[i] = $compileNode[0]
                        }
                    });
                    afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
                    while (linkQueue.length) {
                        var scope = linkQueue.shift(),
                        beforeTemplateLinkNode = linkQueue.shift(),
                        linkRootElement = linkQueue.shift(),
                        controller = linkQueue.shift(),
                        linkNode = $compileNode[0];
                        if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
                            linkNode = JQLiteClone(compileNode);
                            replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode)
                        }
                        afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller)
                    }
                    linkQueue = null
                }).error(function(response, code, headers, config) {
                    throw $compileMinErr("tpload", "Failed to load template: {0}", config.url)
                });
                return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, controller) {
                    if (linkQueue) {
                        linkQueue.push(scope);
                        linkQueue.push(node);
                        linkQueue.push(rootElement);
                        linkQueue.push(controller)
                    } else {
                        afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, controller)
                    }
                }
            }
            function byPriority(a, b) {
                var diff = b.priority - a.priority;
                if (diff !== 0) return diff;
                if (a.name !== b.name) return a.name < b.name ? -1 : 1;
                return a.index - b.index
            }
            function assertNoDuplicate(what, previousDirective, directive, element) {
                if (previousDirective) {
                    throw $compileMinErr("multidir", "Multiple directives [{0}, {1}] asking for {2} on: {3}", previousDirective.name, directive.name, what, startingTag(element))
                }
            }
            function addTextInterpolateDirective(directives, text) {
                var interpolateFn = $interpolate(text, true);
                if (interpolateFn) {
                    directives.push({
                        priority: 0,
                        compile: valueFn(function textInterpolateLinkFn(scope, node) {
                            var parent = node.parent(),
                            bindings = parent.data("$binding") || [];
                            bindings.push(interpolateFn);
                            safeAddClass(parent.data("$binding", bindings), "ng-binding");
                            scope.$watch(interpolateFn,
                            function interpolateFnWatchAction(value) {
                                node[0].nodeValue = value
                            })
                        })
                    })
                }
            }
            function getTrustedContext(node, attrNormalizedName) {
                if (attrNormalizedName == "xlinkHref" || nodeName_(node) != "IMG" && (attrNormalizedName == "src" || attrNormalizedName == "ngSrc")) {
                    return $sce.RESOURCE_URL
                }
            }
            function addAttrInterpolateDirective(node, directives, value, name) {
                var interpolateFn = $interpolate(value, true);
                if (!interpolateFn) return;
                if (name === "multiple" && nodeName_(node) === "SELECT") {
                    throw $compileMinErr("selmulti", "Binding to the 'multiple' attribute is not supported. Element: {0}", startingTag(node))
                }
                directives.push({
                    priority: -100,
                    compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) {
                        var $$observers = attr.$$observers || (attr.$$observers = {});
                        if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
                            throw $compileMinErr("nodomevents", "Interpolations for HTML DOM event attributes are disallowed.  Please use the ng- " + "versions (such as ng-click instead of onclick) instead.")
                        }
                        interpolateFn = $interpolate(attr[name], true, getTrustedContext(node, name));
                        if (!interpolateFn) return;
                        attr[name] = interpolateFn(scope); ($$observers[name] || ($$observers[name] = [])).$$inter = true; (attr.$$observers && attr.$$observers[name].$$scope || scope).$watch(interpolateFn,
                        function interpolateFnWatchAction(value) {
                            attr.$set(name, value)
                        })
                    })
                })
            }
            function replaceWith($rootElement, elementsToRemove, newNode) {
                var firstElementToRemove = elementsToRemove[0],
                removeCount = elementsToRemove.length,
                parent = firstElementToRemove.parentNode,
                i,
                ii;
                if ($rootElement) {
                    for (i = 0, ii = $rootElement.length; i < ii; i++) {
                        if ($rootElement[i] == firstElementToRemove) {
                            $rootElement[i++] = newNode;
                            for (var j = i,
                            j2 = j + removeCount - 1,
                            jj = $rootElement.length; j < jj; j++, j2++) {
                                if (j2 < jj) {
                                    $rootElement[j] = $rootElement[j2]
                                } else {
                                    delete $rootElement[j]
                                }
                            }
                            $rootElement.length -= removeCount - 1;
                            break
                        }
                    }
                }
                if (parent) {
                    parent.replaceChild(newNode, firstElementToRemove)
                }
                var fragment = document.createDocumentFragment();
                fragment.appendChild(firstElementToRemove);
                newNode[jqLite.expando] = firstElementToRemove[jqLite.expando];
                for (var k = 1,
                kk = elementsToRemove.length; k < kk; k++) {
                    var element = elementsToRemove[k];
                    jqLite(element).remove();
                    fragment.appendChild(element);
                    delete elementsToRemove[k]
                }
                elementsToRemove[0] = newNode;
                elementsToRemove.length = 1
            }
        }]
    }
    var PREFIX_REGEXP = /^(x[\:\-_]|data[\:\-_])/i;
    function directiveNormalize(name) {
        return camelCase(name.replace(PREFIX_REGEXP, ""))
    }
    function nodesetLinkingFn(scope, nodeList, rootElement, boundTranscludeFn) {}
    function directiveLinkingFn(nodesetLinkingFn, scope, node, rootElement, boundTranscludeFn) {}
    function $ControllerProvider() {
        var controllers = {},
        CNTRL_REG = /^(\S+)(\s+as\s+(\w+))?$/;
        this.register = function(name, constructor) {
            assertNotHasOwnProperty(name, "controller");
            if (isObject(name)) {
                extend(controllers, name)
            } else {
                controllers[name] = constructor
            }
        };
        this.$get = ["$injector", "$window",
        function($injector, $window) {
            return function(expression, locals) {
                var instance, match, constructor, identifier;
                if (isString(expression)) {
                    match = expression.match(CNTRL_REG),
                    constructor = match[1],
                    identifier = match[3];
                    expression = controllers.hasOwnProperty(constructor) ? controllers[constructor] : getter(locals.$scope, constructor, true) || getter($window, constructor, true);
                    assertArgFn(expression, constructor, true)
                }
                instance = $injector.instantiate(expression, locals);
                if (identifier) {
                    if (! (locals && typeof locals.$scope == "object")) {
                        throw minErr("$controller")("noscp", "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", constructor || expression.name, identifier)
                    }
                    locals.$scope[identifier] = instance
                }
                return instance
            }
        }]
    }
    function $DocumentProvider() {
        this.$get = ["$window",
        function(window) {
            return jqLite(window.document)
        }]
    }
    function $ExceptionHandlerProvider() {
        this.$get = ["$log",
        function($log) {
            return function(exception, cause) {
                $log.error.apply($log, arguments)
            }
        }]
    }
    function parseHeaders(headers) {
        var parsed = {},
        key, val, i;
        if (!headers) return parsed;
        forEach(headers.split("\n"),
        function(line) {
            i = line.indexOf(":");
            key = lowercase(trim(line.substr(0, i)));
            val = trim(line.substr(i + 1));
            if (key) {
                if (parsed[key]) {
                    parsed[key] += ", " + val
                } else {
                    parsed[key] = val
                }
            }
        });
        return parsed
    }
    function headersGetter(headers) {
        var headersObj = isObject(headers) ? headers: undefined;
        return function(name) {
            if (!headersObj) headersObj = parseHeaders(headers);
            if (name) {
                return headersObj[lowercase(name)] || null
            }
            return headersObj
        }
    }
    function transformData(data, headers, fns) {
        if (isFunction(fns)) return fns(data, headers);
        forEach(fns,
        function(fn) {
            data = fn(data, headers)
        });
        return data
    }
    function isSuccess(status) {
        return 200 <= status && status < 300
    }
    function $HttpProvider() {
        var JSON_START = /^\s*(\[|\{[^\{])/,
        JSON_END = /[\}\]]\s*$/,
        PROTECTION_PREFIX = /^\)\]\}',?\n/,
        CONTENT_TYPE_APPLICATION_JSON = {
            "Content-Type": "application/json;charset=utf-8"
        };
        var defaults = this.defaults = {
            transformResponse: [function(data) {
                if (isString(data)) {
                    data = data.replace(PROTECTION_PREFIX, "");
                    if (JSON_START.test(data) && JSON_END.test(data)) data = fromJson(data)
                }
                return data
            }],
            transformRequest: [function(d) {
                return isObject(d) && !isFile(d) ? toJson(d) : d
            }],
            headers: {
                common: {
                    Accept: "application/json, text/plain, */*"
                },
                post: CONTENT_TYPE_APPLICATION_JSON,
                put: CONTENT_TYPE_APPLICATION_JSON,
                patch: CONTENT_TYPE_APPLICATION_JSON
            },
            xsrfCookieName: "XSRF-TOKEN",
            xsrfHeaderName: "X-XSRF-TOKEN"
        };
        var interceptorFactories = this.interceptors = [];
        var responseInterceptorFactories = this.responseInterceptors = [];
        this.$get = ["$httpBackend", "$browser", "$cacheFactory", "$rootScope", "$q", "$injector",
        function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) {
            var defaultCache = $cacheFactory("$http");
            var reversedInterceptors = [];
            forEach(interceptorFactories,
            function(interceptorFactory) {
                reversedInterceptors.unshift(isString(interceptorFactory) ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory))
            });
            forEach(responseInterceptorFactories,
            function(interceptorFactory, index) {
                var responseFn = isString(interceptorFactory) ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory);
                reversedInterceptors.splice(index, 0, {
                    response: function(response) {
                        return responseFn($q.when(response))
                    },
                    responseError: function(response) {
                        return responseFn($q.reject(response))
                    }
                })
            });
            function $http(requestConfig) {
                var config = {
                    transformRequest: defaults.transformRequest,
                    transformResponse: defaults.transformResponse
                };
                var headers = mergeHeaders(requestConfig);
                extend(config, requestConfig);
                config.headers = headers;
                config.method = uppercase(config.method);
                var xsrfValue = urlIsSameOrigin(config.url) ? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName] : undefined;
                if (xsrfValue) {
                    headers[config.xsrfHeaderName || defaults.xsrfHeaderName] = xsrfValue
                }
                var serverRequest = function(config) {
                    headers = config.headers;
                    var reqData = transformData(config.data, headersGetter(headers), config.transformRequest);
                    if (isUndefined(config.data)) {
                        forEach(headers,
                        function(value, header) {
                            if (lowercase(header) === "content-type") {
                                delete headers[header]
                            }
                        })
                    }
                    if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
                        config.withCredentials = defaults.withCredentials
                    }
                    return sendReq(config, reqData, headers).then(transformResponse, transformResponse)
                };
                var chain = [serverRequest, undefined];
                var promise = $q.when(config);
                forEach(reversedInterceptors,
                function(interceptor) {
                    if (interceptor.request || interceptor.requestError) {
                        chain.unshift(interceptor.request, interceptor.requestError)
                    }
                    if (interceptor.response || interceptor.responseError) {
                        chain.push(interceptor.response, interceptor.responseError)
                    }
                });
                while (chain.length) {
                    var thenFn = chain.shift();
                    var rejectFn = chain.shift();
                    promise = promise.then(thenFn, rejectFn)
                }
                promise.success = function(fn) {
                    promise.then(function(response) {
                        fn(response.data, response.status, response.headers, config)
                    });
                    return promise
                };
                promise.error = function(fn) {
                    promise.then(null,
                    function(response) {
                        fn(response.data, response.status, response.headers, config)
                    });
                    return promise
                };
                return promise;
                function transformResponse(response) {
                    var resp = extend({},
                    response, {
                        data: transformData(response.data, response.headers, config.transformResponse)
                    });
                    return isSuccess(response.status) ? resp: $q.reject(resp)
                }
                function mergeHeaders(config) {
                    var defHeaders = defaults.headers,
                    reqHeaders = extend({},
                    config.headers),
                    defHeaderName,
                    lowercaseDefHeaderName,
                    reqHeaderName;
                    defHeaders = extend({},
                    defHeaders.common, defHeaders[lowercase(config.method)]);
                    execHeaders(defHeaders);
                    execHeaders(reqHeaders);
                    defaultHeadersIteration: for (defHeaderName in defHeaders) {
                        lowercaseDefHeaderName = lowercase(defHeaderName);
                        for (reqHeaderName in reqHeaders) {
                            if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
                                continue defaultHeadersIteration
                            }
                        }
                        reqHeaders[defHeaderName] = defHeaders[defHeaderName]
                    }
                    return reqHeaders;
                    function execHeaders(headers) {
                        var headerContent;
                        forEach(headers,
                        function(headerFn, header) {
                            if (isFunction(headerFn)) {
                                headerContent = headerFn();
                                if (headerContent != null) {
                                    headers[header] = headerContent
                                } else {
                                    delete headers[header]
                                }
                            }
                        })
                    }
                }
            }
            $http.pendingRequests = [];
            createShortMethods("get", "delete", "head", "jsonp");
            createShortMethodsWithData("post", "put");
            $http.defaults = defaults;
            return $http;
            function createShortMethods(names) {
                forEach(arguments,
                function(name) {
                    $http[name] = function(url, config) {
                        return $http(extend(config || {},
                        {
                            method: name,
                            url: url
                        }))
                    }
                })
            }
            function createShortMethodsWithData(name) {
                forEach(arguments,
                function(name) {
                    $http[name] = function(url, data, config) {
                        return $http(extend(config || {},
                        {
                            method: name,
                            url: url,
                            data: data
                        }))
                    }
                })
            }
            function sendReq(config, reqData, reqHeaders) {
                var deferred = $q.defer(),
                promise = deferred.promise,
                cache,
                cachedResp,
                url = buildUrl(config.url, config.params);
                $http.pendingRequests.push(config);
                promise.then(removePendingReq, removePendingReq);
                if ((config.cache || defaults.cache) && config.cache !== false && config.method == "GET") {
                    cache = isObject(config.cache) ? config.cache: isObject(defaults.cache) ? defaults.cache: defaultCache
                }
                if (cache) {
                    cachedResp = cache.get(url);
                    if (isDefined(cachedResp)) {
                        if (cachedResp.then) {
                            cachedResp.then(removePendingReq, removePendingReq);
                            return cachedResp
                        } else {
                            if (isArray(cachedResp)) {
                                resolvePromise(cachedResp[1], cachedResp[0], copy(cachedResp[2]))
                            } else {
                                resolvePromise(cachedResp, 200, {})
                            }
                        }
                    } else {
                        cache.put(url, promise)
                    }
                }
                if (isUndefined(cachedResp)) {
                    $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout, config.withCredentials, config.responseType)
                }
                return promise;
                function done(status, response, headersString) {
                    if (cache) {
                        if (isSuccess(status)) {
                            cache.put(url, [status, response, parseHeaders(headersString)])
                        } else {
                            cache.remove(url)
                        }
                    }
                    resolvePromise(response, status, headersString);
                    if (!$rootScope.$$phase) $rootScope.$apply()
                }
                function resolvePromise(response, status, headers) {
                    status = Math.max(status, 0); (isSuccess(status) ? deferred.resolve: deferred.reject)({
                        data: response,
                        status: status,
                        headers: headersGetter(headers),
                        config: config
                    })
                }
                function removePendingReq() {
                    var idx = indexOf($http.pendingRequests, config);
                    if (idx !== -1) $http.pendingRequests.splice(idx, 1)
                }
            }
            function buildUrl(url, params) {
                if (!params) return url;
                var parts = [];
                forEachSorted(params,
                function(value, key) {
                    if (value == null || value == undefined) return;
                    if (!isArray(value)) value = [value];
                    forEach(value,
                    function(v) {
                        if (isObject(v)) {
                            v = toJson(v)
                        }
                        parts.push(encodeUriQuery(key) + "=" + encodeUriQuery(v))
                    })
                });
                return url + (url.indexOf("?") == -1 ? "?": "&") + parts.join("&")
            }
        }]
    }
    var XHR = window.XMLHttpRequest ||
    function() {
        try {
            return new ActiveXObject("Msxml2.XMLHTTP.6.0")
        } catch(e1) {}
        try {
            return new ActiveXObject("Msxml2.XMLHTTP.3.0")
        } catch(e2) {}
        try {
            return new ActiveXObject("Msxml2.XMLHTTP")
        } catch(e3) {}
        throw minErr("$httpBackend")("noxhr", "This browser does not support XMLHttpRequest.")
    };
    function $HttpBackendProvider() {
        this.$get = ["$browser", "$window", "$document",
        function($browser, $window, $document) {
            return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0], $window.location.protocol.replace(":", ""))
        }]
    }
    function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
        return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
            var status;
            $browser.$$incOutstandingRequestCount();
            url = url || $browser.url();
            if (lowercase(method) == "jsonp") {
                var callbackId = "_" + (callbacks.counter++).toString(36);
                callbacks[callbackId] = function(data) {
                    callbacks[callbackId].data = data
                };
                var jsonpDone = jsonpReq(url.replace("JSON_CALLBACK", "angular.callbacks." + callbackId),
                function() {
                    if (callbacks[callbackId].data) {
                        completeRequest(callback, 200, callbacks[callbackId].data)
                    } else {
                        completeRequest(callback, status || -2)
                    }
                    delete callbacks[callbackId]
                })
            } else {
                var xhr = new XHR;
                xhr.open(method, url, true);
                forEach(headers,
                function(value, key) {
                    if (isDefined(value)) {
                        xhr.setRequestHeader(key, value)
                    }
                });
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4) {
                        var responseHeaders = xhr.getAllResponseHeaders();
                        completeRequest(callback, status || xhr.status, xhr.responseType ? xhr.response: xhr.responseText, responseHeaders)
                    }
                };
                if (withCredentials) {
                    xhr.withCredentials = true
                }
                if (responseType) {
                    xhr.responseType = responseType
                }
                xhr.send(post || null)
            }
            if (timeout > 0) {
                var timeoutId = $browserDefer(timeoutRequest, timeout)
            } else if (timeout && timeout.then) {
                timeout.then(timeoutRequest)
            }
            function timeoutRequest() {
                status = -1;
                jsonpDone && jsonpDone();
                xhr && xhr.abort()
            }
            function completeRequest(callback, status, response, headersString) {
                var protocol = locationProtocol || urlResolve(url).protocol;
                timeoutId && $browserDefer.cancel(timeoutId);
                jsonpDone = xhr = null;
                status = protocol == "file" ? response ? 200 : 404 : status;
                status = status == 1223 ? 204 : status;
                callback(status, response, headersString);
                $browser.$$completeOutstandingRequest(noop)
            }
        };
        function jsonpReq(url, done) {
            var script = rawDocument.createElement("script"),
            doneWrapper = function() {
                rawDocument.body.removeChild(script);
                if (done) done()
            };
            script.type = "text/javascript";
            script.src = url;
            if (msie) {
                script.onreadystatechange = function() {
                    if (/loaded|complete/.test(script.readyState)) doneWrapper()
                }
            } else {
                script.onload = script.onerror = doneWrapper
            }
            rawDocument.body.appendChild(script);
            return doneWrapper
        }
    }
    var $interpolateMinErr = minErr("$interpolate");
    function $InterpolateProvider() {
        var startSymbol = "{{";
        var endSymbol = "}}";
        this.startSymbol = function(value) {
            if (value) {
                startSymbol = value;
                return this
            } else {
                return startSymbol
            }
        };
        this.endSymbol = function(value) {
            if (value) {
                endSymbol = value;
                return this
            } else {
                return endSymbol
            }
        };
        this.$get = ["$parse", "$exceptionHandler", "$sce",
        function($parse, $exceptionHandler, $sce) {
            var startSymbolLength = startSymbol.length,
            endSymbolLength = endSymbol.length;
            function $interpolate(text, mustHaveExpression, trustedContext) {
                var startIndex, endIndex, index = 0,
                parts = [],
                length = text.length,
                hasInterpolation = false,
                fn,
                exp,
                concat = [];
                while (index < length) {
                    if ((startIndex = text.indexOf(startSymbol, index)) != -1 && (endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) {
                        index != startIndex && parts.push(text.substring(index, startIndex));
                        parts.push(fn = $parse(exp = text.substring(startIndex + startSymbolLength, endIndex)));
                        fn.exp = exp;
                        index = endIndex + endSymbolLength;
                        hasInterpolation = true
                    } else {
                        index != length && parts.push(text.substring(index));
                        index = length
                    }
                }
                if (! (length = parts.length)) {
                    parts.push("");
                    length = 1
                }
                if (trustedContext && parts.length > 1) {
                    throw $interpolateMinErr("noconcat", "Error while interpolating: {0}\nStrict Contextual Escaping disallows " + "interpolations that concatenate multiple expressions when a trusted value is " + "required.  See http://docs.angularjs.org/api/ng.$sce", text)
                }
                if (!mustHaveExpression || hasInterpolation) {
                    concat.length = length;
                    fn = function(context) {
                        try {
                            for (var i = 0,
                            ii = length,
                            part; i < ii; i++) {
                                if (typeof(part = parts[i]) == "function") {
                                    part = part(context);
                                    if (trustedContext) {
                                        part = $sce.getTrusted(trustedContext, part)
                                    } else {
                                        part = $sce.valueOf(part)
                                    }
                                    if (part == null || part == undefined) {
                                        part = ""
                                    } else if (typeof part != "string") {
                                        part = toJson(part)
                                    }
                                }
                                concat[i] = part
                            }
                            return concat.join("")
                        } catch(err) {
                            var newErr = $interpolateMinErr("interr", "Can't interpolate: {0}\n{1}", text, err.toString());
                            $exceptionHandler(newErr)
                        }
                    };
                    fn.exp = text;
                    fn.parts = parts;
                    return fn
                }
            }
            $interpolate.startSymbol = function() {
                return startSymbol
            };
            $interpolate.endSymbol = function() {
                return endSymbol
            };
            return $interpolate
        }]
    }
    function $IntervalProvider() {
        this.$get = ["$rootScope", "$window", "$q",
        function($rootScope, $window, $q) {
            var intervals = {};
            function interval(fn, delay, count, invokeApply) {
                var setInterval = $window.setInterval,
                clearInterval = $window.clearInterval;
                var deferred = $q.defer(),
                promise = deferred.promise,
                count = isDefined(count) ? count: 0,
                iteration = 0,
                skipApply = isDefined(invokeApply) && !invokeApply;
                promise.then(null, null, fn);
                promise.$$intervalId = setInterval(function tick() {
                    deferred.notify(iteration++);
                    if (count > 0 && iteration >= count) {
                        deferred.resolve(iteration);
                        clearInterval(promise.$$intervalId);
                        delete intervals[promise.$$intervalId]
                    }
                    if (!skipApply) $rootScope.$apply()
                },
                delay);
                intervals[promise.$$intervalId] = deferred;
                return promise
            }
            interval.cancel = function(promise) {
                if (promise && promise.$$intervalId in intervals) {
                    intervals[promise.$$intervalId].reject("canceled");
                    clearInterval(promise.$$intervalId);
                    delete intervals[promise.$$intervalId];
                    return true
                }
                return false
            };
            return interval
        }]
    }
    function $LocaleProvider() {
        this.$get = function() {
            return {
                id: "en-us",
                NUMBER_FORMATS: {
                    DECIMAL_SEP: ".",
                    GROUP_SEP: ",",
                    PATTERNS: [{
                        minInt: 1,
                        minFrac: 0,
                        maxFrac: 3,
                        posPre: "",
                        posSuf: "",
                        negPre: "-",
                        negSuf: "",
                        gSize: 3,
                        lgSize: 3
                    },
                    {
                        minInt: 1,
                        minFrac: 2,
                        maxFrac: 2,
                        posPre: "¤",
                        posSuf: "",
                        negPre: "(¤",
                        negSuf: ")",
                        gSize: 3,
                        lgSize: 3
                    }],
                    CURRENCY_SYM: "$"
                },
                DATETIME_FORMATS: {
                    MONTH: "January,February,March,April,May,June,July,August,September,October,November,December".split(","),
                    SHORTMONTH: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),
                    DAY: "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),
                    SHORTDAY: "Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),
                    AMPMS: ["AM", "PM"],
                    medium: "MMM d, y h:mm:ss a",
                    "short": "M/d/yy h:mm a",
                    fullDate: "EEEE, MMMM d, y",
                    longDate: "MMMM d, y",
                    mediumDate: "MMM d, y",
                    shortDate: "M/d/yy",
                    mediumTime: "h:mm:ss a",
                    shortTime: "h:mm a"
                },
                pluralCat: function(num) {
                    if (num === 1) {
                        return "one"
                    }
                    return "other"
                }
            }
        }
    }
    var PATH_MATCH = /^([^\?#]*)(\?([^#]*))?(#(.*))?$/,
    DEFAULT_PORTS = {
        http: 80,
        https: 443,
        ftp: 21
    };
    var $locationMinErr = minErr("$location");
    function encodePath(path) {
        var segments = path.split("/"),
        i = segments.length;
        while (i--) {
            segments[i] = encodeUriSegment(segments[i])
        }
        return segments.join("/")
    }
    function parseAbsoluteUrl(absoluteUrl, locationObj) {
        var parsedUrl = urlResolve(absoluteUrl);
        locationObj.$$protocol = parsedUrl.protocol;
        locationObj.$$host = parsedUrl.hostname;
        locationObj.$$port = int(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null
    }
    function parseAppUrl(relativeUrl, locationObj) {
        var prefixed = relativeUrl.charAt(0) !== "/";
        if (prefixed) {
            relativeUrl = "/" + relativeUrl
        }
        var match = urlResolve(relativeUrl);
        locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === "/" ? match.pathname.substring(1) : match.pathname);
        locationObj.$$search = parseKeyValue(match.search);
        locationObj.$$hash = decodeURIComponent(match.hash);
        if (locationObj.$$path && locationObj.$$path.charAt(0) != "/") locationObj.$$path = "/" + locationObj.$$path
    }
    function beginsWith(begin, whole) {
        if (whole.indexOf(begin) == 0) {
            return whole.substr(begin.length)
        }
    }
    function stripHash(url) {
        var index = url.indexOf("#");
        return index == -1 ? url: url.substr(0, index)
    }
    function stripFile(url) {
        return url.substr(0, stripHash(url).lastIndexOf("/") + 1)
    }
    function serverBase(url) {
        return url.substring(0, url.indexOf("/", url.indexOf("//") + 2))
    }
    function LocationHtml5Url(appBase, basePrefix) {
        this.$$html5 = true;
        basePrefix = basePrefix || "";
        var appBaseNoFile = stripFile(appBase);
        parseAbsoluteUrl(appBase, this);
        this.$$parse = function(url) {
            var pathUrl = beginsWith(appBaseNoFile, url);
            if (!isString(pathUrl)) {
                throw $locationMinErr("ipthprfx", 'Invalid url "{0}", missing path prefix "{1}".', url, appBaseNoFile)
            }
            parseAppUrl(pathUrl, this);
            if (!this.$$path) {
                this.$$path = "/"
            }
            this.$$compose()
        };
        this.$$compose = function() {
            var search = toKeyValue(this.$$search),
            hash = this.$$hash ? "#" + encodeUriSegment(this.$$hash) : "";
            this.$$url = encodePath(this.$$path) + (search ? "?" + search: "") + hash;
            this.$$absUrl = appBaseNoFile + this.$$url.substr(1)
        };
        this.$$rewrite = function(url) {
            var appUrl, prevAppUrl;
            if ((appUrl = beginsWith(appBase, url)) !== undefined) {
                prevAppUrl = appUrl;
                if ((appUrl = beginsWith(basePrefix, appUrl)) !== undefined) {
                    return appBaseNoFile + (beginsWith("/", appUrl) || appUrl)
                } else {
                    return appBase + prevAppUrl
                }
            } else if ((appUrl = beginsWith(appBaseNoFile, url)) !== undefined) {
                return appBaseNoFile + appUrl
            } else if (appBaseNoFile == url + "/") {
                return appBaseNoFile
            }
        }
    }
    function LocationHashbangUrl(appBase, hashPrefix) {
        var appBaseNoFile = stripFile(appBase);
        parseAbsoluteUrl(appBase, this);
        this.$$parse = function(url) {
            var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url);
            var withoutHashUrl = withoutBaseUrl.charAt(0) == "#" ? beginsWith(hashPrefix, withoutBaseUrl) : this.$$html5 ? withoutBaseUrl: "";
            if (!isString(withoutHashUrl)) {
                throw $locationMinErr("ihshprfx", 'Invalid url "{0}", missing hash prefix "{1}".', url, hashPrefix)
            }
            parseAppUrl(withoutHashUrl, this);
            this.$$compose()
        };
        this.$$compose = function() {
            var search = toKeyValue(this.$$search),
            hash = this.$$hash ? "#" + encodeUriSegment(this.$$hash) : "";
            this.$$url = encodePath(this.$$path) + (search ? "?" + search: "") + hash;
            this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url: "")
        };
        this.$$rewrite = function(url) {
            if (stripHash(appBase) == stripHash(url)) {
                return url
            }
        }
    }
    function LocationHashbangInHtml5Url(appBase, hashPrefix) {
        this.$$html5 = true;
        LocationHashbangUrl.apply(this, arguments);
        var appBaseNoFile = stripFile(appBase);
        this.$$rewrite = function(url) {
            var appUrl;
            if (appBase == stripHash(url)) {
                return url
            } else if (appUrl = beginsWith(appBaseNoFile, url)) {
                return appBase + hashPrefix + appUrl
            } else if (appBaseNoFile === url + "/") {
                return appBaseNoFile
            }
        }
    }
    LocationHashbangInHtml5Url.prototype = LocationHashbangUrl.prototype = LocationHtml5Url.prototype = {
        $$html5: false,
        $$replace: false,
        absUrl: locationGetter("$$absUrl"),
        url: function(url, replace) {
            if (isUndefined(url)) return this.$$url;
            var match = PATH_MATCH.exec(url);
            if (match[1]) this.path(decodeURIComponent(match[1]));
            if (match[2] || match[1]) this.search(match[3] || "");
            this.hash(match[5] || "", replace);
            return this
        },
        protocol: locationGetter("$$protocol"),
        host: locationGetter("$$host"),
        port: locationGetter("$$port"),
        path: locationGetterSetter("$$path",
        function(path) {
            return path.charAt(0) == "/" ? path: "/" + path
        }),
        search: function(search, paramValue) {
            switch (arguments.length) {
            case 0:
                return this.$$search;
            case 1:
                if (isString(search)) {
                    this.$$search = parseKeyValue(search)
                } else if (isObject(search)) {
                    this.$$search = search
                } else {
                    throw $locationMinErr("isrcharg", "The first argument of the `$location#search()` call must be a string or an object.")
                }
                break;
            default:
                if (paramValue == undefined || paramValue == null) {
                    delete this.$$search[search]
                } else {
                    this.$$search[search] = paramValue
                }
            }
            this.$$compose();
            return this
        },
        hash: locationGetterSetter("$$hash", identity),
        replace: function() {
            this.$$replace = true;
            return this
        }
    };
    function locationGetter(property) {
        return function() {
            return this[property]
        }
    }
    function locationGetterSetter(property, preprocess) {
        return function(value) {
            if (isUndefined(value)) return this[property];
            this[property] = preprocess(value);
            this.$$compose();
            return this
        }
    }
    function $LocationProvider() {
        var hashPrefix = "",
        html5Mode = false;
        this.hashPrefix = function(prefix) {
            if (isDefined(prefix)) {
                hashPrefix = prefix;
                return this
            } else {
                return hashPrefix
            }
        };
        this.html5Mode = function(mode) {
            if (isDefined(mode)) {
                html5Mode = mode;
                return this
            } else {
                return html5Mode
            }
        };
        this.$get = ["$rootScope", "$browser", "$sniffer", "$rootElement",
        function($rootScope, $browser, $sniffer, $rootElement) {
            var $location, LocationMode, baseHref = $browser.baseHref(),
            initialUrl = $browser.url(),
            appBase;
            if (html5Mode) {
                appBase = serverBase(initialUrl) + (baseHref || "/");
                LocationMode = $sniffer.history ? LocationHtml5Url: LocationHashbangInHtml5Url
            } else {
                appBase = stripHash(initialUrl);
                LocationMode = LocationHashbangUrl
            }
            $location = new LocationMode(appBase, "#" + hashPrefix);
            $location.$$parse($location.$$rewrite(initialUrl));
            $rootElement.on("click",
            function(event) {
                if (event.ctrlKey || event.metaKey || event.which == 2) return;
                var elm = jqLite(event.target);
                while (lowercase(elm[0].nodeName) !== "a") {
                    if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return
                }
                var absHref = elm.prop("href");
                var rewrittenUrl = $location.$$rewrite(absHref);
                if (absHref && !elm.attr("target") && rewrittenUrl && !event.isDefaultPrevented()) {
                    event.preventDefault();
                    if (rewrittenUrl != $browser.url()) {
                        $location.$$parse(rewrittenUrl);
                        $rootScope.$apply();
                        window.angular["ff-684208-preventDefault"] = true
                    }
                }
            });
            if ($location.absUrl() != initialUrl) {
                $browser.url($location.absUrl(), true)
            }
            $browser.onUrlChange(function(newUrl) {
                if ($location.absUrl() != newUrl) {
                    if ($rootScope.$broadcast("$locationChangeStart", newUrl, $location.absUrl()).defaultPrevented) {
                        $browser.url($location.absUrl());
                        return
                    }
                    $rootScope.$evalAsync(function() {
                        var oldUrl = $location.absUrl();
                        $location.$$parse(newUrl);
                        afterLocationChange(oldUrl)
                    });
                    if (!$rootScope.$$phase) $rootScope.$digest()
                }
            });
            var changeCounter = 0;
            $rootScope.$watch(function $locationWatch() {
                var oldUrl = $browser.url();
                var currentReplace = $location.$$replace;
                if (!changeCounter || oldUrl != $location.absUrl()) {
                    changeCounter++;
                    $rootScope.$evalAsync(function() {
                        if ($rootScope.$broadcast("$locationChangeStart", $location.absUrl(), oldUrl).defaultPrevented) {
                            $location.$$parse(oldUrl)
                        } else {
                            $browser.url($location.absUrl(), currentReplace);
                            afterLocationChange(oldUrl)
                        }
                    })
                }
                $location.$$replace = false;
                return changeCounter
            });
            return $location;
            function afterLocationChange(oldUrl) {
                $rootScope.$broadcast("$locationChangeSuccess", $location.absUrl(), oldUrl)
            }
        }]
    }
    function $LogProvider() {
        var debug = true,
        self = this;
        this.debugEnabled = function(flag) {
            if (isDefined(flag)) {
                debug = flag;
                return this
            } else {
                return debug
            }
        };
        this.$get = ["$window",
        function($window) {
            return {
                log: consoleLog("log"),
                info: consoleLog("info"),
                warn: consoleLog("warn"),
                error: consoleLog("error"),
                debug: function() {
                    var fn = consoleLog("debug");
                    return function() {
                        if (debug) {
                            fn.apply(self, arguments)
                        }
                    }
                } ()
            };
            function formatError(arg) {
                if (arg instanceof Error) {
                    if (arg.stack) {
                        arg = arg.message && arg.stack.indexOf(arg.message) === -1 ? "Error: " + arg.message + "\n" + arg.stack: arg.stack
                    } else if (arg.sourceURL) {
                        arg = arg.message + "\n" + arg.sourceURL + ":" + arg.line
                    }
                }
                return arg
            }
            function consoleLog(type) {
                var console = $window.console || {},
                logFn = console[type] || console.log || noop;
                if (logFn.apply) {
                    return function() {
                        var args = [];
                        forEach(arguments,
                        function(arg) {
                            args.push(formatError(arg))
                        });
                        return logFn.apply(console, args)
                    }
                }
                return function(arg1, arg2) {
                    logFn(arg1, arg2 == null ? "": arg2)
                }
            }
        }]
    }
    var $parseMinErr = minErr("$parse");
    var promiseWarningCache = {};
    var promiseWarning;
    function ensureSafeMemberName(name, fullExpression) {
        if (name === "constructor") {
            throw $parseMinErr("isecfld", 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', fullExpression)
        }
        return name
    }
    function ensureSafeObject(obj, fullExpression) {
        if (obj && obj.constructor === obj) {
            throw $parseMinErr("isecfn", "Referencing Function in Angular expressions is disallowed! Expression: {0}", fullExpression)
        } else if (obj && obj.document && obj.location && obj.alert && obj.setInterval) {
            throw $parseMinErr("isecwindow", "Referencing the Window in Angular expressions is disallowed! Expression: {0}", fullExpression)
        } else if (obj && (obj.nodeName || obj.on && obj.find)) {
            throw $parseMinErr("isecdom", "Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}", fullExpression)
        } else {
            return obj
        }
    }
    var OPERATORS = {
        "null": function() {
            return null
        },
        "true": function() {
            return true
        },
        "false": function() {
            return false
        },
        undefined: noop,
        "+": function(self, locals, a, b) {
            a = a(self, locals);
            b = b(self, locals);
            if (isDefined(a)) {
                if (isDefined(b)) {
                    return a + b
                }
                return a
            }
            return isDefined(b) ? b: undefined
        },
        "-": function(self, locals, a, b) {
            a = a(self, locals);
            b = b(self, locals);
            return (isDefined(a) ? a: 0) - (isDefined(b) ? b: 0)
        },
        "*": function(self, locals, a, b) {
            return a(self, locals) * b(self, locals)
        },
        "/": function(self, locals, a, b) {
            return a(self, locals) / b(self, locals)
        },
        "%": function(self, locals, a, b) {
            return a(self, locals) % b(self, locals)
        },
        "^": function(self, locals, a, b) {
            return a(self, locals) ^ b(self, locals)
        },
        "=": noop,
        "===": function(self, locals, a, b) {
            return a(self, locals) === b(self, locals)
        },
        "!==": function(self, locals, a, b) {
            return a(self, locals) !== b(self, locals)
        },
        "==": function(self, locals, a, b) {
            return a(self, locals) == b(self, locals)
        },
        "!=": function(self, locals, a, b) {
            return a(self, locals) != b(self, locals)
        },
        "<": function(self, locals, a, b) {
            return a(self, locals) < b(self, locals)
        },
        ">": function(self, locals, a, b) {
            return a(self, locals) > b(self, locals)
        },
        "<=": function(self, locals, a, b) {
            return a(self, locals) <= b(self, locals)
        },
        ">=": function(self, locals, a, b) {
            return a(self, locals) >= b(self, locals)
        },
        "&&": function(self, locals, a, b) {
            return a(self, locals) && b(self, locals)
        },
        "||": function(self, locals, a, b) {
            return a(self, locals) || b(self, locals)
        },
        "&": function(self, locals, a, b) {
            return a(self, locals) & b(self, locals)
        },
        "|": function(self, locals, a, b) {
            return b(self, locals)(self, locals, a(self, locals))
        },
        "!": function(self, locals, a) {
            return ! a(self, locals)
        }
    };
    var ESCAPE = {
        n: "\n",
        f: "\f",
        r: "\r",
        t: "	",
        v: "",
        "'": "'",
        '"': '"'
    };
    var Lexer = function(options) {
        this.options = options
    };
    Lexer.prototype = {
        constructor: Lexer,
        lex: function(text) {
            this.text = text;
            this.index = 0;
            this.ch = undefined;
            this.lastCh = ":";
            this.tokens = [];
            var token;
            var json = [];
            while (this.index < this.text.length) {
                this.ch = this.text.charAt(this.index);
                if (this.is("\"'")) {
                    this.readString(this.ch)
                } else if (this.isNumber(this.ch) || this.is(".") && this.isNumber(this.peek())) {
                    this.readNumber()
                } else if (this.isIdent(this.ch)) {
                    this.readIdent();
                    if (this.was("{,") && json[0] === "{" && (token = this.tokens[this.tokens.length - 1])) {
                        token.json = token.text.indexOf(".") === -1
                    }
                } else if (this.is("(){}[].,;:?")) {
                    this.tokens.push({
                        index: this.index,
                        text: this.ch,
                        json: this.was(":[,") && this.is("{[") || this.is("}]:,")
                    });
                    if (this.is("{[")) json.unshift(this.ch);
                    if (this.is("}]")) json.shift();
                    this.index++
                } else if (this.isWhitespace(this.ch)) {
                    this.index++;
                    continue
                } else {
                    var ch2 = this.ch + this.peek();
                    var ch3 = ch2 + this.peek(2);
                    var fn = OPERATORS[this.ch];
                    var fn2 = OPERATORS[ch2];
                    var fn3 = OPERATORS[ch3];
                    if (fn3) {
                        this.tokens.push({
                            index: this.index,
                            text: ch3,
                            fn: fn3
                        });
                        this.index += 3
                    } else if (fn2) {
                        this.tokens.push({
                            index: this.index,
                            text: ch2,
                            fn: fn2
                        });
                        this.index += 2
                    } else if (fn) {
                        this.tokens.push({
                            index: this.index,
                            text: this.ch,
                            fn: fn,
                            json: this.was("[,:") && this.is("+-")
                        });
                        this.index += 1
                    } else {
                        this.throwError("Unexpected next character ", this.index, this.index + 1)
                    }
                }
                this.lastCh = this.ch
            }
            return this.tokens
        },
        is: function(chars) {
            return chars.indexOf(this.ch) !== -1
        },
        was: function(chars) {
            return chars.indexOf(this.lastCh) !== -1
        },
        peek: function(i) {
            var num = i || 1;
            return this.index + num < this.text.length ? this.text.charAt(this.index + num) : false
        },
        isNumber: function(ch) {
            return "0" <= ch && ch <= "9"
        },
        isWhitespace: function(ch) {
            return ch === " " || ch === "\r" || ch === "	" || ch === "\n" || ch === "" || ch === " "
        },
        isIdent: function(ch) {
            return "a" <= ch && ch <= "z" || "A" <= ch && ch <= "Z" || "_" === ch || ch === "$"
        },
        isExpOperator: function(ch) {
            return ch === "-" || ch === "+" || this.isNumber(ch)
        },
        throwError: function(error, start, end) {
            end = end || this.index;
            var colStr = isDefined(start) ? "s " + start + "-" + this.index + " [" + this.text.substring(start, end) + "]": " " + end;
            throw $parseMinErr("lexerr", "Lexer Error: {0} at column{1} in expression [{2}].", error, colStr, this.text)
        },
        readNumber: function() {
            var number = "";
            var start = this.index;
            while (this.index < this.text.length) {
                var ch = lowercase(this.text.charAt(this.index));
                if (ch == "." || this.isNumber(ch)) {
                    number += ch
                } else {
                    var peekCh = this.peek();
                    if (ch == "e" && this.isExpOperator(peekCh)) {
                        number += ch
                    } else if (this.isExpOperator(ch) && peekCh && this.isNumber(peekCh) && number.charAt(number.length - 1) == "e") {
                        number += ch
                    } else if (this.isExpOperator(ch) && (!peekCh || !this.isNumber(peekCh)) && number.charAt(number.length - 1) == "e") {
                        this.throwError("Invalid exponent")
                    } else {
                        break
                    }
                }
                this.index++
            }
            number = 1 * number;
            this.tokens.push({
                index: start,
                text: number,
                json: true,
                fn: function() {
                    return number
                }
            })
        },
        readIdent: function() {
            var parser = this;
            var ident = "";
            var start = this.index;
            var lastDot, peekIndex, methodName, ch;
            while (this.index < this.text.length) {
                ch = this.text.charAt(this.index);
                if (ch === "." || this.isIdent(ch) || this.isNumber(ch)) {
                    if (ch === ".") lastDot = this.index;
                    ident += ch
                } else {
                    break
                }
                this.index++
            }
            if (lastDot) {
                peekIndex = this.index;
                while (peekIndex < this.text.length) {
                    ch = this.text.charAt(peekIndex);
                    if (ch === "(") {
                        methodName = ident.substr(lastDot - start + 1);
                        ident = ident.substr(0, lastDot - start);
                        this.index = peekIndex;
                        break
                    }
                    if (this.isWhitespace(ch)) {
                        peekIndex++
                    } else {
                        break
                    }
                }
            }
            var token = {
                index: start,
                text: ident
            };
            if (OPERATORS.hasOwnProperty(ident)) {
                token.fn = OPERATORS[ident];
                token.json = OPERATORS[ident]
            } else {
                var getter = getterFn(ident, this.options, this.text);
                token.fn = extend(function(self, locals) {
                    return getter(self, locals)
                },
                {
                    assign: function(self, value) {
                        return setter(self, ident, value, parser.text, parser.options)
                    }
                })
            }
            this.tokens.push(token);
            if (methodName) {
                this.tokens.push({
                    index: lastDot,
                    text: ".",
                    json: false
                });
                this.tokens.push({
                    index: lastDot + 1,
                    text: methodName,
                    json: false
                })
            }
        },
        readString: function(quote) {
            var start = this.index;
            this.index++;
            var string = "";
            var rawString = quote;
            var escape = false;
            while (this.index < this.text.length) {
                var ch = this.text.charAt(this.index);
                rawString += ch;
                if (escape) {
                    if (ch === "u") {
                        var hex = this.text.substring(this.index + 1, this.index + 5);
                        if (!hex.match(/[\da-f]{4}/i)) this.throwError("Invalid unicode escape [\\u" + hex + "]");
                        this.index += 4;
                        string += String.fromCharCode(parseInt(hex, 16))
                    } else {
                        var rep = ESCAPE[ch];
                        if (rep) {
                            string += rep
                        } else {
                            string += ch
                        }
                    }
                    escape = false
                } else if (ch === "\\") {
                    escape = true
                } else if (ch === quote) {
                    this.index++;
                    this.tokens.push({
                        index: start,
                        text: rawString,
                        string: string,
                        json: true,
                        fn: function() {
                            return string
                        }
                    });
                    return
                } else {
                    string += ch
                }
                this.index++
            }
            this.throwError("Unterminated quote", start)
        }
    };
    var Parser = function(lexer, $filter, options) {
        this.lexer = lexer;
        this.$filter = $filter;
        this.options = options
    };
    Parser.ZERO = function() {
        return 0
    };
    Parser.prototype = {
        constructor: Parser,
        parse: function(text, json) {
            this.text = text;
            this.json = json;
            this.tokens = this.lexer.lex(text);
            if (json) {
                this.assignment = this.logicalOR;
                this.functionCall = this.fieldAccess = this.objectIndex = this.filterChain = function() {
                    this.throwError("is not valid json", {
                        text: text,
                        index: 0
                    })
                }
            }
            var value = json ? this.primary() : this.statements();
            if (this.tokens.length !== 0) {
                this.throwError("is an unexpected token", this.tokens[0])
            }
            value.literal = !!value.literal;
            value.constant = !!value.constant;
            return value
        },
        primary: function() {
            var primary;
            if (this.expect("(")) {
                primary = this.filterChain();
                this.consume(")")
            } else if (this.expect("[")) {
                primary = this.arrayDeclaration()
            } else if (this.expect("{")) {
                primary = this.object()
            } else {
                var token = this.expect();
                primary = token.fn;
                if (!primary) {
                    this.throwError("not a primary expression", token)
                }
                if (token.json) {
                    primary.constant = true;
                    primary.literal = true
                }
            }
            var next, context;
            while (next = this.expect("(", "[", ".")) {
                if (next.text === "(") {
                    primary = this.functionCall(primary, context);
                    context = null
                } else if (next.text === "[") {
                    context = primary;
                    primary = this.objectIndex(primary)
                } else if (next.text === ".") {
                    context = primary;
                    primary = this.fieldAccess(primary)
                } else {
                    this.throwError("IMPOSSIBLE")
                }
            }
            return primary
        },
        throwError: function(msg, token) {
            throw $parseMinErr("syntax", "Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}].", token.text, msg, token.index + 1, this.text, this.text.substring(token.index))
        },
        peekToken: function() {
            if (this.tokens.length === 0) throw $parseMinErr("ueoe", "Unexpected end of expression: {0}", this.text);
            return this.tokens[0]
        },
        peek: function(e1, e2, e3, e4) {
            if (this.tokens.length > 0) {
                var token = this.tokens[0];
                var t = token.text;
                if (t === e1 || t === e2 || t === e3 || t === e4 || !e1 && !e2 && !e3 && !e4) {
                    return token
                }
            }
            return false
        },
        expect: function(e1, e2, e3, e4) {
            var token = this.peek(e1, e2, e3, e4);
            if (token) {
                if (this.json && !token.json) {
                    this.throwError("is not valid json", token)
                }
                this.tokens.shift();
                return token
            }
            return false
        },
        consume: function(e1) {
            if (!this.expect(e1)) {
                this.throwError("is unexpected, expecting [" + e1 + "]", this.peek())
            }
        },
        unaryFn: function(fn, right) {
            return extend(function(self, locals) {
                return fn(self, locals, right)
            },
            {
                constant: right.constant
            })
        },
        ternaryFn: function(left, middle, right) {
            return extend(function(self, locals) {
                return left(self, locals) ? middle(self, locals) : right(self, locals)
            },
            {
                constant: left.constant && middle.constant && right.constant
            })
        },
        binaryFn: function(left, fn, right) {
            return extend(function(self, locals) {
                return fn(self, locals, left, right)
            },
            {
                constant: left.constant && right.constant
            })
        },
        statements: function() {
            var statements = [];
            while (true) {
                if (this.tokens.length > 0 && !this.peek("}", ")", ";", "]")) statements.push(this.filterChain());
                if (!this.expect(";")) {
                    return statements.length === 1 ? statements[0] : function(self, locals) {
                        var value;
                        for (var i = 0; i < statements.length; i++) {
                            var statement = statements[i];
                            if (statement) {
                                value = statement(self, locals)
                            }
                        }
                        return value
                    }
                }
            }
        },
        filterChain: function() {
            var left = this.expression();
            var token;
            while (true) {
                if (token = this.expect("|")) {
                    left = this.binaryFn(left, token.fn, this.filter())
                } else {
                    return left
                }
            }
        },
        filter: function() {
            var token = this.expect();
            var fn = this.$filter(token.text);
            var argsFn = [];
            while (true) {
                if (token = this.expect(":")) {
                    argsFn.push(this.expression())
                } else {
                    var fnInvoke = function(self, locals, input) {
                        var args = [input];
                        for (var i = 0; i < argsFn.length; i++) {
                            args.push(argsFn[i](self, locals))
                        }
                        return fn.apply(self, args)
                    };
                    return function() {
                        return fnInvoke
                    }
                }
            }
        },
        expression: function() {
            return this.assignment()
        },
        assignment: function() {
            var left = this.ternary();
            var right;
            var token;
            if (token = this.expect("=")) {
                if (!left.assign) {
                    this.throwError("implies assignment but [" + this.text.substring(0, token.index) + "] can not be assigned to", token)
                }
                right = this.ternary();
                return function(scope, locals) {
                    return left.assign(scope, right(scope, locals), locals)
                }
            }
            return left
        },
        ternary: function() {
            var left = this.logicalOR();
            var middle;
            var token;
            if (token = this.expect("?")) {
                middle = this.ternary();
                if (token = this.expect(":")) {
                    return this.ternaryFn(left, middle, this.ternary())
                } else {
                    this.throwError("expected :", token)
                }
            } else {
                return left
            }
        },
        logicalOR: function() {
            var left = this.logicalAND();
            var token;
            while (true) {
                if (token = this.expect("||")) {
                    left = this.binaryFn(left, token.fn, this.logicalAND())
                } else {
                    return left
                }
            }
        },
        logicalAND: function() {
            var left = this.equality();
            var token;
            if (token = this.expect("&&")) {
                left = this.binaryFn(left, token.fn, this.logicalAND())
            }
            return left
        },
        equality: function() {
            var left = this.relational();
            var token;
            if (token = this.expect("==", "!=", "===", "!==")) {
                left = this.binaryFn(left, token.fn, this.equality())
            }
            return left
        },
        relational: function() {
            var left = this.additive();
            var token;
            if (token = this.expect("<", ">", "<=", ">=")) {
                left = this.binaryFn(left, token.fn, this.relational())
            }
            return left
        },
        additive: function() {
            var left = this.multiplicative();
            var token;
            while (token = this.expect("+", "-")) {
                left = this.binaryFn(left, token.fn, this.multiplicative())
            }
            return left
        },
        multiplicative: function() {
            var left = this.unary();
            var token;
            while (token = this.expect("*", "/", "%")) {
                left = this.binaryFn(left, token.fn, this.unary())
            }
            return left
        },
        unary: function() {
            var token;
            if (this.expect("+")) {
                return this.primary()
            } else if (token = this.expect("-")) {
                return this.binaryFn(Parser.ZERO, token.fn, this.unary())
            } else if (token = this.expect("!")) {
                return this.unaryFn(token.fn, this.unary())
            } else {
                return this.primary()
            }
        },
        fieldAccess: function(object) {
            var parser = this;
            var field = this.expect().text;
            var getter = getterFn(field, this.options, this.text);
            return extend(function(scope, locals, self) {
                return getter(self || object(scope, locals), locals)
            },
            {
                assign: function(scope, value, locals) {
                    return setter(object(scope, locals), field, value, parser.text, parser.options)
                }
            })
        },
        objectIndex: function(obj) {
            var parser = this;
            var indexFn = this.expression();
            this.consume("]");
            return extend(function(self, locals) {
                var o = obj(self, locals),
                i = indexFn(self, locals),
                v,
                p;
                if (!o) return undefined;
                v = ensureSafeObject(o[i], parser.text);
                if (v && v.then && parser.options.unwrapPromises) {
                    p = v;
                    if (! ("$$v" in v)) {
                        p.$$v = undefined;
                        p.then(function(val) {
                            p.$$v = val
                        })
                    }
                    v = v.$$v
                }
                return v
            },
            {
                assign: function(self, value, locals) {
                    var key = indexFn(self, locals);
                    var safe = ensureSafeObject(obj(self, locals), parser.text);
                    return safe[key] = value
                }
            })
        },
        functionCall: function(fn, contextGetter) {
            var argsFn = [];
            if (this.peekToken().text !== ")") {
                do {
                    argsFn.push(this.expression())
                } while ( this . expect (","))
            }
            this.consume(")");
            var parser = this;
            return function(scope, locals) {
                var args = [];
                var context = contextGetter ? contextGetter(scope, locals) : scope;
                for (var i = 0; i < argsFn.length; i++) {
                    args.push(argsFn[i](scope, locals))
                }
                var fnPtr = fn(scope, locals, context) || noop;
                ensureSafeObject(fnPtr, parser.text);
                var v = fnPtr.apply ? fnPtr.apply(context, args) : fnPtr(args[0], args[1], args[2], args[3], args[4]);
                return ensureSafeObject(v, parser.text)
            }
        },
        arrayDeclaration: function() {
            var elementFns = [];
            var allConstant = true;
            if (this.peekToken().text !== "]") {
                do {
                    var elementFn = this.expression();
                    elementFns.push(elementFn);
                    if (!elementFn.constant) {
                        allConstant = false
                    }
                } while ( this . expect (","))
            }
            this.consume("]");
            return extend(function(self, locals) {
                var array = [];
                for (var i = 0; i < elementFns.length; i++) {
                    array.push(elementFns[i](self, locals))
                }
                return array
            },
            {
                literal: true,
                constant: allConstant
            })
        },
        object: function() {
            var keyValues = [];
            var allConstant = true;
            if (this.peekToken().text !== "}") {
                do {
                    var token = this.expect(), key = token.string || token.text;
                    this.consume(":");
                    var value = this.expression();
                    keyValues.push({
                        key: key,
                        value: value
                    });
                    if (!value.constant) {
                        allConstant = false
                    }
                } while ( this . expect (","))
            }
            this.consume("}");
            return extend(function(self, locals) {
                var object = {};
                for (var i = 0; i < keyValues.length; i++) {
                    var keyValue = keyValues[i];
                    object[keyValue.key] = keyValue.value(self, locals)
                }
                return object
            },
            {
                literal: true,
                constant: allConstant
            })
        }
    };
    function setter(obj, path, setValue, fullExp, options) {
        options = options || {};
        var element = path.split("."),
        key;
        for (var i = 0; element.length > 1; i++) {
            key = ensureSafeMemberName(element.shift(), fullExp);
            var propertyObj = obj[key];
            if (!propertyObj) {
                propertyObj = {};
                obj[key] = propertyObj
            }
            obj = propertyObj;
            if (obj.then && options.unwrapPromises) {
                promiseWarning(fullExp);
                if (! ("$$v" in obj)) { (function(promise) {
                        promise.then(function(val) {
                            promise.$$v = val
                        })
                    })(obj)
                }
                if (obj.$$v === undefined) {
                    obj.$$v = {}
                }
                obj = obj.$$v
            }
        }
        key = ensureSafeMemberName(element.shift(), fullExp);
        obj[key] = setValue;
        return setValue
    }
    var getterFnCache = {};
    function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
        ensureSafeMemberName(key0, fullExp);
        ensureSafeMemberName(key1, fullExp);
        ensureSafeMemberName(key2, fullExp);
        ensureSafeMemberName(key3, fullExp);
        ensureSafeMemberName(key4, fullExp);
        return ! options.unwrapPromises ?
        function cspSafeGetter(scope, locals) {
            var pathVal = locals && locals.hasOwnProperty(key0) ? locals: scope;
            if (pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key0];
            if (!key1 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key1];
            if (!key2 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key2];
            if (!key3 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key3];
            if (!key4 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key4];
            return pathVal
        }: function cspSafePromiseEnabledGetter(scope, locals) {
            var pathVal = locals && locals.hasOwnProperty(key0) ? locals: scope,
            promise;
            if (pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key0];
            if (pathVal && pathVal.then) {
                promiseWarning(fullExp);
                if (! ("$$v" in pathVal)) {
                    promise = pathVal;
                    promise.$$v = undefined;
                    promise.then(function(val) {
                        promise.$$v = val
                    })
                }
                pathVal = pathVal.$$v
            }
            if (!key1 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key1];
            if (pathVal && pathVal.then) {
                promiseWarning(fullExp);
                if (! ("$$v" in pathVal)) {
                    promise = pathVal;
                    promise.$$v = undefined;
                    promise.then(function(val) {
                        promise.$$v = val
                    })
                }
                pathVal = pathVal.$$v
            }
            if (!key2 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key2];
            if (pathVal && pathVal.then) {
                promiseWarning(fullExp);
                if (! ("$$v" in pathVal)) {
                    promise = pathVal;
                    promise.$$v = undefined;
                    promise.then(function(val) {
                        promise.$$v = val
                    })
                }
                pathVal = pathVal.$$v
            }
            if (!key3 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key3];
            if (pathVal && pathVal.then) {
                promiseWarning(fullExp);
                if (! ("$$v" in pathVal)) {
                    promise = pathVal;
                    promise.$$v = undefined;
                    promise.then(function(val) {
                        promise.$$v = val
                    })
                }
                pathVal = pathVal.$$v
            }
            if (!key4 || pathVal === null || pathVal === undefined) return pathVal;
            pathVal = pathVal[key4];
            if (pathVal && pathVal.then) {
                promiseWarning(fullExp);
                if (! ("$$v" in pathVal)) {
                    promise = pathVal;
                    promise.$$v = undefined;
                    promise.then(function(val) {
                        promise.$$v = val
                    })
                }
                pathVal = pathVal.$$v
            }
            return pathVal
        }
    }
    function getterFn(path, options, fullExp) {
        if (getterFnCache.hasOwnProperty(path)) {
            return getterFnCache[path]
        }
        var pathKeys = path.split("."),
        pathKeysLength = pathKeys.length,
        fn;
        if (options.csp) {
            fn = pathKeysLength < 6 ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, options) : function(scope, locals) {
                var i = 0,
                val;
                do {
                    val = cspSafeGetterFn(pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], fullExp, options)(scope, locals);
                    locals = undefined;
                    scope = val
                } while ( i < pathKeysLength );
                return val
            }
        } else {
            var code = "var l, fn, p;\n";
            forEach(pathKeys,
            function(key, index) {
                ensureSafeMemberName(key, fullExp);
                code += "if(s === null || s === undefined) return s;\n" + "l=s;\n" + "s=" + (index ? "s": '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ";\n" + (options.unwrapPromises ? "if (s && s.then) {\n" + ' pw("' + fullExp.replace(/\"/g, '\\"') + '");\n' + ' if (!("$$v" in s)) {\n' + " p=s;\n" + " p.$$v = undefined;\n" + " p.then(function(v) {p.$$v=v;});\n" + "}\n" + " s=s.$$v\n" + "}\n": "")
            });
            code += "return s;";
            var evaledFnGetter = Function("s", "k", "pw", code);
            evaledFnGetter.toString = function() {
                return code
            };
            fn = function(scope, locals) {
                return evaledFnGetter(scope, locals, promiseWarning)
            }
        }
        if (path !== "hasOwnProperty") {
            getterFnCache[path] = fn
        }
        return fn
    }
    function $ParseProvider() {
        var cache = {};
        var $parseOptions = {
            csp: false,
            unwrapPromises: false,
            logPromiseWarnings: true
        };
        this.unwrapPromises = function(value) {
            if (isDefined(value)) {
                $parseOptions.unwrapPromises = !!value;
                return this
            } else {
                return $parseOptions.unwrapPromises
            }
        };
        this.logPromiseWarnings = function(value) {
            if (isDefined(value)) {
                $parseOptions.logPromiseWarnings = value;
                return this
            } else {
                return $parseOptions.logPromiseWarnings
            }
        };
        this.$get = ["$filter", "$sniffer", "$log",
        function($filter, $sniffer, $log) {
            $parseOptions.csp = $sniffer.csp;
            promiseWarning = function promiseWarningFn(fullExp) {
                if (!$parseOptions.logPromiseWarnings || promiseWarningCache.hasOwnProperty(fullExp)) return;
                promiseWarningCache[fullExp] = true;
                $log.warn("[$parse] Promise found in the expression `" + fullExp + "`. " + "Automatic unwrapping of promises in Angular expressions is deprecated.")
            };
            return function(exp) {
                var parsedExpression;
                switch (typeof exp) {
                case "string":
                    if (cache.hasOwnProperty(exp)) {
                        return cache[exp]
                    }
                    var lexer = new Lexer($parseOptions);
                    var parser = new Parser(lexer, $filter, $parseOptions);
                    parsedExpression = parser.parse(exp, false);
                    if (exp !== "hasOwnProperty") {
                        cache[exp] = parsedExpression
                    }
                    return parsedExpression;
                case "function":
                    return exp;
                default:
                    return noop
                }
            }
        }]
    }
    function $QProvider() {
        this.$get = ["$rootScope", "$exceptionHandler",
        function($rootScope, $exceptionHandler) {
            return qFactory(function(callback) {
                $rootScope.$evalAsync(callback)
            },
            $exceptionHandler)
        }]
    }
    function qFactory(nextTick, exceptionHandler) {
        var defer = function() {
            var pending = [],
            value,
            deferred;
            deferred = {
                resolve: function(val) {
                    if (pending) {
                        var callbacks = pending;
                        pending = undefined;
                        value = ref(val);
                        if (callbacks.length) {
                            nextTick(function() {
                                var callback;
                                for (var i = 0,
                                ii = callbacks.length; i < ii; i++) {
                                    callback = callbacks[i];
                                    value.then(callback[0], callback[1], callback[2])
                                }
                            })
                        }
                    }
                },
                reject: function(reason) {
                    deferred.resolve(reject(reason))
                },
                notify: function(progress) {
                    if (pending) {
                        var callbacks = pending;
                        if (pending.length) {
                            nextTick(function() {
                                var callback;
                                for (var i = 0,
                                ii = callbacks.length; i < ii; i++) {
                                    callback = callbacks[i];
                                    callback[2](progress)
                                }
                            })
                        }
                    }
                },
                promise: {
                    then: function(callback, errback, progressback) {
                        var result = defer();
                        var wrappedCallback = function(value) {
                            try {
                                result.resolve((isFunction(callback) ? callback: defaultCallback)(value))
                            } catch(e) {
                                result.reject(e);
                                exceptionHandler(e)
                            }
                        };
                        var wrappedErrback = function(reason) {
                            try {
                                result.resolve((isFunction(errback) ? errback: defaultErrback)(reason))
                            } catch(e) {
                                result.reject(e);
                                exceptionHandler(e)
                            }
                        };
                        var wrappedProgressback = function(progress) {
                            try {
                                result.notify((isFunction(progressback) ? progressback: defaultCallback)(progress))
                            } catch(e) {
                                exceptionHandler(e)
                            }
                        };
                        if (pending) {
                            pending.push([wrappedCallback, wrappedErrback, wrappedProgressback])
                        } else {
                            value.then(wrappedCallback, wrappedErrback, wrappedProgressback)
                        }
                        return result.promise
                    },
                    "catch": function(callback) {
                        return this.then(null, callback)
                    },
                    "finally": function(callback) {
                        function makePromise(value, resolved) {
                            var result = defer();
                            if (resolved) {
                                result.resolve(value)
                            } else {
                                result.reject(value)
                            }
                            return result.promise
                        }
                        function handleCallback(value, isResolved) {
                            var callbackOutput = null;
                            try {
                                callbackOutput = (callback || defaultCallback)()
                            } catch(e) {
                                return makePromise(e, false)
                            }
                            if (callbackOutput && isFunction(callbackOutput.then)) {
                                return callbackOutput.then(function() {
                                    return makePromise(value, isResolved)
                                },
                                function(error) {
                                    return makePromise(error, false)
                                })
                            } else {
                                return makePromise(value, isResolved)
                            }
                        }
                        return this.then(function(value) {
                            return handleCallback(value, true)
                        },
                        function(error) {
                            return handleCallback(error, false)
                        })
                    }
                }
            };
            return deferred
        };
        var ref = function(value) {
            if (value && isFunction(value.then)) return value;
            return {
                then: function(callback) {
                    var result = defer();
                    nextTick(function() {
                        result.resolve(callback(value))
                    });
                    return result.promise
                }
            }
        };
        var reject = function(reason) {
            return {
                then: function(callback, errback) {
                    var result = defer();
                    nextTick(function() {
                        try {
                            result.resolve((isFunction(errback) ? errback: defaultErrback)(reason))
                        } catch(e) {
                            result.reject(e);
                            exceptionHandler(e)
                        }
                    });
                    return result.promise
                }
            }
        };
        var when = function(value, callback, errback, progressback) {
            var result = defer(),
            done;
            var wrappedCallback = function(value) {
                try {
                    return (isFunction(callback) ? callback: defaultCallback)(value)
                } catch(e) {
                    exceptionHandler(e);
                    return reject(e)
                }
            };
            var wrappedErrback = function(reason) {
                try {
                    return (isFunction(errback) ? errback: defaultErrback)(reason)
                } catch(e) {
                    exceptionHandler(e);
                    return reject(e)
                }
            };
            var wrappedProgressback = function(progress) {
                try {
                    return (isFunction(progressback) ? progressback: defaultCallback)(progress)
                } catch(e) {
                    exceptionHandler(e)
                }
            };
            nextTick(function() {
                ref(value).then(function(value) {
                    if (done) return;
                    done = true;
                    result.resolve(ref(value).then(wrappedCallback, wrappedErrback, wrappedProgressback))
                },
                function(reason) {
                    if (done) return;
                    done = true;
                    result.resolve(wrappedErrback(reason))
                },
                function(progress) {
                    if (done) return;
                    result.notify(wrappedProgressback(progress))
                })
            });
            return result.promise
        };
        function defaultCallback(value) {
            return value
        }
        function defaultErrback(reason) {
            return reject(reason)
        }
        function all(promises) {
            var deferred = defer(),
            counter = 0,
            results = isArray(promises) ? [] : {};
            forEach(promises,
            function(promise, key) {
                counter++;
                ref(promise).then(function(value) {
                    if (results.hasOwnProperty(key)) return;
                    results[key] = value;
                    if (!--counter) deferred.resolve(results)
                },
                function(reason) {
                    if (results.hasOwnProperty(key)) return;
                    deferred.reject(reason)
                })
            });
            if (counter === 0) {
                deferred.resolve(results)
            }
            return deferred.promise
        }
        return {
            defer: defer,
            reject: reject,
            when: when,
            all: all
        }
    }
    function $RootScopeProvider() {
        var TTL = 10;
        var $rootScopeMinErr = minErr("$rootScope");
        this.digestTtl = function(value) {
            if (arguments.length) {
                TTL = value
            }
            return TTL
        };
        this.$get = ["$injector", "$exceptionHandler", "$parse", "$browser",
        function($injector, $exceptionHandler, $parse, $browser) {
            function Scope() {
                this.$id = nextUid();
                this.$$phase = this.$parent = this.$$watchers = this.$$nextSibling = this.$$prevSibling = this.$$childHead = this.$$childTail = null;
                this["this"] = this.$root = this;
                this.$$destroyed = false;
                this.$$asyncQueue = [];
                this.$$postDigestQueue = [];
                this.$$listeners = {};
                this.$$isolateBindings = {}
            }
            Scope.prototype = {
                constructor: Scope,
                $new: function(isolate) {
                    var Child, child;
                    if (isolate) {
                        child = new Scope;
                        child.$root = this.$root;
                        child.$$asyncQueue = this.$$asyncQueue;
                        child.$$postDigestQueue = this.$$postDigestQueue
                    } else {
                        Child = function() {};
                        Child.prototype = this;
                        child = new Child;
                        child.$id = nextUid()
                    }
                    child["this"] = child;
                    child.$$listeners = {};
                    child.$parent = this;
                    child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
                    child.$$prevSibling = this.$$childTail;
                    if (this.$$childHead) {
                        this.$$childTail.$$nextSibling = child;
                        this.$$childTail = child
                    } else {
                        this.$$childHead = this.$$childTail = child
                    }
                    return child
                },
                $watch: function(watchExp, listener, objectEquality) {
                    var scope = this,
                    get = compileToFn(watchExp, "watch"),
                    array = scope.$$watchers,
                    watcher = {
                        fn: listener,
                        last: initWatchVal,
                        get: get,
                        exp: watchExp,
                        eq: !!objectEquality
                    };
                    if (!isFunction(listener)) {
                        var listenFn = compileToFn(listener || noop, "listener");
                        watcher.fn = function(newVal, oldVal, scope) {
                            listenFn(scope)
                        }
                    }
                    if (typeof watchExp == "string" && get.constant) {
                        var originalFn = watcher.fn;
                        watcher.fn = function(newVal, oldVal, scope) {
                            originalFn.call(this, newVal, oldVal, scope);
                            arrayRemove(array, watcher)
                        }
                    }
                    if (!array) {
                        array = scope.$$watchers = []
                    }
                    array.unshift(watcher);
                    return function() {
                        arrayRemove(array, watcher)
                    }
                },
                $watchCollection: function(obj, listener) {
                    var self = this;
                    var oldValue;
                    var newValue;
                    var changeDetected = 0;
                    var objGetter = $parse(obj);
                    var internalArray = [];
                    var internalObject = {};
                    var oldLength = 0;
                    function $watchCollectionWatch() {
                        newValue = objGetter(self);
                        var newLength, key;
                        if (!isObject(newValue)) {
                            if (oldValue !== newValue) {
                                oldValue = newValue;
                                changeDetected++
                            }
                        } else if (isArrayLike(newValue)) {
                            if (oldValue !== internalArray) {
                                oldValue = internalArray;
                                oldLength = oldValue.length = 0;
                                changeDetected++
                            }
                            newLength = newValue.length;
                            if (oldLength !== newLength) {
                                changeDetected++;
                                oldValue.length = oldLength = newLength
                            }
                            for (var i = 0; i < newLength; i++) {
                                if (oldValue[i] !== newValue[i]) {
                                    changeDetected++;
                                    oldValue[i] = newValue[i]
                                }
                            }
                        } else {
                            if (oldValue !== internalObject) {
                                oldValue = internalObject = {};
                                oldLength = 0;
                                changeDetected++
                            }
                            newLength = 0;
                            for (key in newValue) {
                                if (newValue.hasOwnProperty(key)) {
                                    newLength++;
                                    if (oldValue.hasOwnProperty(key)) {
                                        if (oldValue[key] !== newValue[key]) {
                                            changeDetected++;
                                            oldValue[key] = newValue[key]
                                        }
                                    } else {
                                        oldLength++;
                                        oldValue[key] = newValue[key];
                                        changeDetected++
                                    }
                                }
                            }
                            if (oldLength > newLength) {
                                changeDetected++;
                                for (key in oldValue) {
                                    if (oldValue.hasOwnProperty(key) && !newValue.hasOwnProperty(key)) {
                                        oldLength--;
                                        delete oldValue[key]
                                    }
                                }
                            }
                        }
                        return changeDetected
                    }
                    function $watchCollectionAction() {
                        listener(newValue, oldValue, self)
                    }
                    return this.$watch($watchCollectionWatch, $watchCollectionAction)
                },
                $digest: function() {
                    var watch, value, last, watchers, asyncQueue = this.$$asyncQueue,
                    postDigestQueue = this.$$postDigestQueue,
                    length, dirty, ttl = TTL,
                    next, current, target = this,
                    watchLog = [],
                    logIdx,
                    logMsg,
                    asyncTask;
                    beginPhase("$digest");
                    do {
                        dirty = false;
                        current = target;
                        while (asyncQueue.length) {
                            try {
                                asyncTask = asyncQueue.shift();
                                asyncTask.scope.$eval(asyncTask.expression)
                            } catch(e) {
                                $exceptionHandler(e)
                            }
                        }
                        do {
                            if (watchers = current.$$watchers) {
                                length = watchers.length;
                                while (length--) {
                                    try {
                                        watch = watchers[length];
                                        if (watch && (value = watch.get(current)) !== (last = watch.last) && !(watch.eq ? equals(value, last) : typeof value == "number" && typeof last == "number" && isNaN(value) && isNaN(last))) {
                                            dirty = true;
                                            watch.last = watch.eq ? copy(value) : value;
                                            watch.fn(value, last === initWatchVal ? value: last, current);
                                            if (ttl < 5) {
                                                logIdx = 4 - ttl;
                                                if (!watchLog[logIdx]) watchLog[logIdx] = [];
                                                logMsg = isFunction(watch.exp) ? "fn: " + (watch.exp.name || watch.exp.toString()) : watch.exp;
                                                logMsg += "; newVal: " + toJson(value) + "; oldVal: " + toJson(last);
                                                watchLog[logIdx].push(logMsg)
                                            }
                                        }
                                    } catch(e) {
                                        $exceptionHandler(e)
                                    }
                                }
                            }
                            if (! (next = current.$$childHead || current !== target && current.$$nextSibling)) {
                                while (current !== target && !(next = current.$$nextSibling)) {
                                    current = current.$parent
                                }
                            }
                        } while ( current = next );
                        if (dirty && !ttl--) {
                            clearPhase();
                            throw $rootScopeMinErr("infdig", "{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}", TTL, toJson(watchLog))
                        }
                    } while ( dirty || asyncQueue . length );
                    clearPhase();
                    while (postDigestQueue.length) {
                        try {
                            postDigestQueue.shift()()
                        } catch(e) {
                            $exceptionHandler(e)
                        }
                    }
                },
                $destroy: function() {
                    if ($rootScope == this || this.$$destroyed) return;
                    var parent = this.$parent;
                    this.$broadcast("$destroy");
                    this.$$destroyed = true;
                    if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
                    if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
                    if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
                    if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;
                    this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead = this.$$childTail = null
                },
                $eval: function(expr, locals) {
                    return $parse(expr)(this, locals)
                },
                $evalAsync: function(expr) {
                    if (!$rootScope.$$phase && !$rootScope.$$asyncQueue.length) {
                        $browser.defer(function() {
                            if ($rootScope.$$asyncQueue.length) {
                                $rootScope.$digest()
                            }
                        })
                    }
                    this.$$asyncQueue.push({
                        scope: this,
                        expression: expr
                    })
                },
                $$postDigest: function(fn) {
                    this.$$postDigestQueue.push(fn)
                },
                $apply: function(expr) {
                    try {
                        beginPhase("$apply");
                        return this.$eval(expr)
                    } catch(e) {
                        $exceptionHandler(e)
                    } finally {
                        clearPhase();
                        try {
                            $rootScope.$digest()
                        } catch(e) {
                            $exceptionHandler(e);
                            throw e
                        }
                    }
                },
                $on: function(name, listener) {
                    var namedListeners = this.$$listeners[name];
                    if (!namedListeners) {
                        this.$$listeners[name] = namedListeners = []
                    }
                    namedListeners.push(listener);
                    return function() {
                        namedListeners[indexOf(namedListeners, listener)] = null
                    }
                },
                $emit: function(name, args) {
                    var empty = [],
                    namedListeners,
                    scope = this,
                    stopPropagation = false,
                    event = {
                        name: name,
                        targetScope: scope,
                        stopPropagation: function() {
                            stopPropagation = true
                        },
                        preventDefault: function() {
                            event.defaultPrevented = true
                        },
                        defaultPrevented: false
                    },
                    listenerArgs = concat([event], arguments, 1),
                    i,
                    length;
                    do {
                        namedListeners = scope.$$listeners[name] || empty;
                        event.currentScope = scope;
                        for (i = 0, length = namedListeners.length; i < length; i++) {
                            if (!namedListeners[i]) {
                                namedListeners.splice(i, 1);
                                i--;
                                length--;
                                continue
                            }
                            try {
                                namedListeners[i].apply(null, listenerArgs)
                            } catch(e) {
                                $exceptionHandler(e)
                            }
                        }
                        if (stopPropagation) return event;
                        scope = scope.$parent
                    } while ( scope );
                    return event
                },
                $broadcast: function(name, args) {
                    var target = this,
                    current = target,
                    next = target,
                    event = {
                        name: name,
                        targetScope: target,
                        preventDefault: function() {
                            event.defaultPrevented = true
                        },
                        defaultPrevented: false
                    },
                    listenerArgs = concat([event], arguments, 1),
                    listeners,
                    i,
                    length;
                    do {
                        current = next;
                        event.currentScope = current;
                        listeners = current.$$listeners[name] || [];
                        for (i = 0, length = listeners.length; i < length; i++) {
                            if (!listeners[i]) {
                                listeners.splice(i, 1);
                                i--;
                                length--;
                                continue
                            }
                            try {
                                listeners[i].apply(null, listenerArgs)
                            } catch(e) {
                                $exceptionHandler(e)
                            }
                        }
                        if (! (next = current.$$childHead || current !== target && current.$$nextSibling)) {
                            while (current !== target && !(next = current.$$nextSibling)) {
                                current = current.$parent
                            }
                        }
                    } while ( current = next );
                    return event
                }
            };
            var $rootScope = new Scope;
            return $rootScope;
            function beginPhase(phase) {
                if ($rootScope.$$phase) {
                    throw $rootScopeMinErr("inprog", "{0} already in progress", $rootScope.$$phase)
                }
                $rootScope.$$phase = phase
            }
            function clearPhase() {
                $rootScope.$$phase = null
            }
            function compileToFn(exp, name) {
                var fn = $parse(exp);
                assertArgFn(fn, name);
                return fn
            }
            function initWatchVal() {}
        }]
    }
    var $sceMinErr = minErr("$sce");
    var SCE_CONTEXTS = {
        HTML: "html",
        CSS: "css",
        URL: "url",
        RESOURCE_URL: "resourceUrl",
        JS: "js"
    };
    function escapeForRegexp(s) {
        return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, "\\$1").replace(/\x08/g, "\\x08")
    }
    function adjustMatcher(matcher) {
        if (matcher === "self") {
            return matcher
        } else if (isString(matcher)) {
            if (matcher.indexOf("***") > -1) {
                throw $sceMinErr("iwcard", "Illegal sequence *** in string matcher.  String: {0}", matcher)
            }
            matcher = escapeForRegexp(matcher).replace("\\*\\*", ".*").replace("\\*", "[^:/.?&;]*");
            return new RegExp("^" + matcher + "$")
        } else if (isRegExp(matcher)) {
            return new RegExp("^" + matcher.source + "$")
        } else {
            throw $sceMinErr("imatcher", 'Matchers may only be "self", string patterns or RegExp objects')
        }
    }
    function adjustMatchers(matchers) {
        var adjustedMatchers = [];
        if (isDefined(matchers)) {
            forEach(matchers,
            function(matcher) {
                adjustedMatchers.push(adjustMatcher(matcher))
            })
        }
        return adjustedMatchers
    }
    function $SceDelegateProvider() {
        this.SCE_CONTEXTS = SCE_CONTEXTS;
        var resourceUrlWhitelist = ["self"],
        resourceUrlBlacklist = [];
        this.resourceUrlWhitelist = function(value) {
            if (arguments.length) {
                resourceUrlWhitelist = adjustMatchers(value)
            }
            return resourceUrlWhitelist
        };
        this.resourceUrlBlacklist = function(value) {
            if (arguments.length) {
                resourceUrlBlacklist = adjustMatchers(value)
            }
            return resourceUrlBlacklist
        };
        this.$get = ["$log", "$document", "$injector",
        function($log, $document, $injector) {
            var htmlSanitizer = function htmlSanitizer(html) {
                throw $sceMinErr("unsafe", "Attempting to use an unsafe value in a safe context.")
            };
            if ($injector.has("$sanitize")) {
                htmlSanitizer = $injector.get("$sanitize")
            }
            function matchUrl(matcher, parsedUrl) {
                if (matcher === "self") {
                    return urlIsSameOrigin(parsedUrl)
                } else {
                    return !! matcher.exec(parsedUrl.href)
                }
            }
            function isResourceUrlAllowedByPolicy(url) {
                var parsedUrl = urlResolve(url.toString());
                var i, n, allowed = false;
                for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {
                    if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {
                        allowed = true;
                        break
                    }
                }
                if (allowed) {
                    for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {
                        if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {
                            allowed = false;
                            break
                        }
                    }
                }
                return allowed
            }
            function generateHolderType(base) {
                var holderType = function TrustedValueHolderType(trustedValue) {
                    this.$$unwrapTrustedValue = function() {
                        return trustedValue
                    }
                };
                if (base) {
                    holderType.prototype = new base
                }
                holderType.prototype.valueOf = function sceValueOf() {
                    return this.$$unwrapTrustedValue()
                };
                holderType.prototype.toString = function sceToString() {
                    return this.$$unwrapTrustedValue().toString()
                };
                return holderType
            }
            var trustedValueHolderBase = generateHolderType(),
            byType = {};
            byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);
            byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);
            byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);
            byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);
            byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);
            function trustAs(type, trustedValue) {
                var constructor = byType.hasOwnProperty(type) ? byType[type] : null;
                if (!constructor) {
                    throw $sceMinErr("icontext", "Attempted to trust a value in invalid context. Context: {0}; Value: {1}", type, trustedValue)
                }
                if (trustedValue === null || trustedValue === undefined || trustedValue === "") {
                    return trustedValue
                }
                if (typeof trustedValue !== "string") {
                    throw $sceMinErr("itype", "Attempted to trust a non-string value in a content requiring a string: Context: {0}", type)
                }
                return new constructor(trustedValue)
            }
            function valueOf(maybeTrusted) {
                if (maybeTrusted instanceof trustedValueHolderBase) {
                    return maybeTrusted.$$unwrapTrustedValue()
                } else {
                    return maybeTrusted
                }
            }
            function getTrusted(type, maybeTrusted) {
                if (maybeTrusted === null || maybeTrusted === undefined || maybeTrusted === "") {
                    return maybeTrusted
                }
                var constructor = byType.hasOwnProperty(type) ? byType[type] : null;
                if (constructor && maybeTrusted instanceof constructor) {
                    return maybeTrusted.$$unwrapTrustedValue()
                }
                if (type === SCE_CONTEXTS.RESOURCE_URL) {
                    if (isResourceUrlAllowedByPolicy(maybeTrusted)) {
                        return maybeTrusted
                    } else {
                        throw $sceMinErr("insecurl", "Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}", maybeTrusted.toString())
                    }
                } else if (type === SCE_CONTEXTS.HTML) {
                    return htmlSanitizer(maybeTrusted)
                }
                throw $sceMinErr("unsafe", "Attempting to use an unsafe value in a safe context.")
            }
            return {
                trustAs: trustAs,
                getTrusted: getTrusted,
                valueOf: valueOf
            }
        }]
    }
    function $SceProvider() {
        var enabled = true;
        this.enabled = function(value) {
            if (arguments.length) {
                enabled = !!value
            }
            return enabled
        };
        this.$get = ["$parse", "$document", "$sceDelegate",
        function($parse, $document, $sceDelegate) {
            if (enabled && msie) {
                var documentMode = $document[0].documentMode;
                if (documentMode !== undefined && documentMode < 8) {
                    throw $sceMinErr("iequirks", "Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks " + "mode.  You can fix this by adding the text <!doctype html> to the top of your HTML " + "document.  See http://docs.angularjs.org/api/ng.$sce for more information.")
                }
            }
            var sce = copy(SCE_CONTEXTS);
            sce.isEnabled = function() {
                return enabled
            };
            sce.trustAs = $sceDelegate.trustAs;
            sce.getTrusted = $sceDelegate.getTrusted;
            sce.valueOf = $sceDelegate.valueOf;
            if (!enabled) {
                sce.trustAs = sce.getTrusted = function(type, value) {
                    return value
                },
                sce.valueOf = identity
            }
            sce.parseAs = function sceParseAs(type, expr) {
                var parsed = $parse(expr);
                if (parsed.literal && parsed.constant) {
                    return parsed
                } else {
                    return function sceParseAsTrusted(self, locals) {
                        return sce.getTrusted(type, parsed(self, locals))
                    }
                }
            };
            var parse = sce.parseAs,
            getTrusted = sce.getTrusted,
            trustAs = sce.trustAs;
            forEach(SCE_CONTEXTS,
            function(enumValue, name) {
                var lName = lowercase(name);
                sce[camelCase("parse_as_" + lName)] = function(expr) {
                    return parse(enumValue, expr)
                };
                sce[camelCase("get_trusted_" + lName)] = function(value) {
                    return getTrusted(enumValue, value)
                };
                sce[camelCase("trust_as_" + lName)] = function(value) {
                    return trustAs(enumValue, value)
                }
            });
            return sce
        }]
    }
    function $SnifferProvider() {
        this.$get = ["$window", "$document",
        function($window, $document) {
            var eventSupport = {},
            android = int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
            boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
            document = $document[0] || {},
            vendorPrefix,
            vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
            bodyStyle = document.body && document.body.style,
            transitions = false,
            animations = false,
            match;
            if (bodyStyle) {
                for (var prop in bodyStyle) {
                    if (match = vendorRegex.exec(prop)) {
                        vendorPrefix = match[0];
                        vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1);
                        break
                    }
                }
                if (!vendorPrefix) {
                    vendorPrefix = "WebkitOpacity" in bodyStyle && "webkit"
                }
                transitions = !!("transition" in bodyStyle || vendorPrefix + "Transition" in bodyStyle);
                animations = !!("animation" in bodyStyle || vendorPrefix + "Animation" in bodyStyle);
                if (android && (!transitions || !animations)) {
                    transitions = isString(document.body.style.webkitTransition);
                    animations = isString(document.body.style.webkitAnimation)
                }
            }
            return {
                history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee),
                hashchange: "onhashchange" in $window && (!document.documentMode || document.documentMode > 7),
                hasEvent: function(event) {
                    if (event == "input" && msie == 9) return false;
                    if (isUndefined(eventSupport[event])) {
                        var divElm = document.createElement("div");
                        eventSupport[event] = "on" + event in divElm
                    }
                    return eventSupport[event]
                },
                csp: document.securityPolicy ? document.securityPolicy.isActive: false,
                vendorPrefix: vendorPrefix,
                transitions: transitions,
                animations: animations
            }
        }]
    }
    function $TimeoutProvider() {
        this.$get = ["$rootScope", "$browser", "$q", "$exceptionHandler",
        function($rootScope, $browser, $q, $exceptionHandler) {
            var deferreds = {};
            function timeout(fn, delay, invokeApply) {
                var deferred = $q.defer(),
                promise = deferred.promise,
                skipApply = isDefined(invokeApply) && !invokeApply,
                timeoutId;
                timeoutId = $browser.defer(function() {
                    try {
                        deferred.resolve(fn())
                    } catch(e) {
                        deferred.reject(e);
                        $exceptionHandler(e)
                    } finally {
                        delete deferreds[promise.$$timeoutId]
                    }
                    if (!skipApply) $rootScope.$apply()
                },
                delay);
                promise.$$timeoutId = timeoutId;
                deferreds[timeoutId] = deferred;
                return promise
            }
            timeout.cancel = function(promise) {
                if (promise && promise.$$timeoutId in deferreds) {
                    deferreds[promise.$$timeoutId].reject("canceled");
                    delete deferreds[promise.$$timeoutId];
                    return $browser.defer.cancel(promise.$$timeoutId)
                }
                return false
            };
            return timeout
        }]
    }
    var urlParsingNode = document.createElement("a");
    var originUrl = urlResolve(window.location.href, true);
    function urlResolve(url) {
        var href = url;
        if (msie) {
            urlParsingNode.setAttribute("href", href);
            href = urlParsingNode.href
        }
        urlParsingNode.setAttribute("href", href);
        return {
            href: urlParsingNode.href,
            protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, "") : "",
            host: urlParsingNode.host,
            search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, "") : "",
            hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, "") : "",
            hostname: urlParsingNode.hostname,
            port: urlParsingNode.port,
            pathname: urlParsingNode.pathname && urlParsingNode.pathname.charAt(0) === "/" ? urlParsingNode.pathname: "/" + urlParsingNode.pathname
        }
    }
    function urlIsSameOrigin(requestUrl) {
        var parsed = isString(requestUrl) ? urlResolve(requestUrl) : requestUrl;
        return parsed.protocol === originUrl.protocol && parsed.host === originUrl.host
    }
    function $WindowProvider() {
        this.$get = valueFn(window)
    }
    $FilterProvider.$inject = ["$provide"];
    function $FilterProvider($provide) {
        var suffix = "Filter";
        function register(name, factory) {
            if (isObject(name)) {
                var filters = {};
                forEach(name,
                function(filter, key) {
                    filters[key] = register(key, filter)
                });
                return filters
            } else {
                return $provide.factory(name + suffix, factory)
            }
        }
        this.register = register;
        this.$get = ["$injector",
        function($injector) {
            return function(name) {
                return $injector.get(name + suffix)
            }
        }];
        register("currency", currencyFilter);
        register("date", dateFilter);
        register("filter", filterFilter);
        register("json", jsonFilter);
        register("limitTo", limitToFilter);
        register("lowercase", lowercaseFilter);
        register("number", numberFilter);
        register("orderBy", orderByFilter);
        register("uppercase", uppercaseFilter)
    }
    function filterFilter() {
        return function(array, expression, comperator) {
            if (!isArray(array)) return array;
            var predicates = [];
            predicates.check = function(value) {
                for (var j = 0; j < predicates.length; j++) {
                    if (!predicates[j](value)) {
                        return false
                    }
                }
                return true
            };
            switch (typeof comperator) {
            case "function":
                break;
            case "boolean":
                if (comperator == true) {
                    comperator = function(obj, text) {
                        return angular.equals(obj, text)
                    };
                    break
                }
            default:
                comperator = function(obj, text) {
                    text = ("" + text).toLowerCase();
                    return ("" + obj).toLowerCase().indexOf(text) > -1
                }
            }
            var search = function(obj, text) {
                if (typeof text == "string" && text.charAt(0) === "!") {
                    return ! search(obj, text.substr(1))
                }
                switch (typeof obj) {
                case "boolean":
                case "number":
                case "string":
                    return comperator(obj, text);
                case "object":
                    switch (typeof text) {
                    case "object":
                        return comperator(obj, text);
                        break;
                    default:
                        for (var objKey in obj) {
                            if (objKey.charAt(0) !== "$" && search(obj[objKey], text)) {
                                return true
                            }
                        }
                        break
                    }
                    return false;
                case "array":
                    for (var i = 0; i < obj.length; i++) {
                        if (search(obj[i], text)) {
                            return true
                        }
                    }
                    return false;
                default:
                    return false
                }
            };
            switch (typeof expression) {
            case "boolean":
            case "number":
            case "string":
                expression = {
                    $: expression
                };
            case "object":
                for (var key in expression) {
                    if (key == "$") { (function() {
                            if (!expression[key]) return;
                            var path = key;
                            predicates.push(function(value) {
                                return search(value, expression[path])
                            })
                        })()
                    } else { (function() {
                            if (typeof expression[key] == "undefined") {
                                return
                            }
                            var path = key;
                            predicates.push(function(value) {
                                return search(getter(value, path), expression[path])
                            })
                        })()
                    }
                }
                break;
            case "function":
                predicates.push(expression);
                break;
            default:
                return array
            }
            var filtered = [];
            for (var j = 0; j < array.length; j++) {
                var value = array[j];
                if (predicates.check(value)) {
                    filtered.push(value)
                }
            }
            return filtered
        }
    }
    currencyFilter.$inject = ["$locale"];
    function currencyFilter($locale) {
        var formats = $locale.NUMBER_FORMATS;
        return function(amount, currencySymbol) {
            if (isUndefined(currencySymbol)) currencySymbol = formats.CURRENCY_SYM;
            return formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, 2).replace(/\u00A4/g, currencySymbol)
        }
    }
    numberFilter.$inject = ["$locale"];
    function numberFilter($locale) {
        var formats = $locale.NUMBER_FORMATS;
        return function(number, fractionSize) {
            return formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize)
        }
    }
    var DECIMAL_SEP = ".";
    function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
        if (isNaN(number) || !isFinite(number)) return "";
        var isNegative = number < 0;
        number = Math.abs(number);
        var numStr = number + "",
        formatedText = "",
        parts = [];
        var hasExponent = false;
        if (numStr.indexOf("e") !== -1) {
            var match = numStr.match(/([\d\.]+)e(-?)(\d+)/);
            if (match && match[2] == "-" && match[3] > fractionSize + 1) {
                numStr = "0"
            } else {
                formatedText = numStr;
                hasExponent = true
            }
        }
        if (!hasExponent) {
            var fractionLen = (numStr.split(DECIMAL_SEP)[1] || "").length;
            if (isUndefined(fractionSize)) {
                fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac)
            }
            var pow = Math.pow(10, fractionSize);
            number = Math.round(number * pow) / pow;
            var fraction = ("" + number).split(DECIMAL_SEP);
            var whole = fraction[0];
            fraction = fraction[1] || "";
            var pos = 0,
            lgroup = pattern.lgSize,
            group = pattern.gSize;
            if (whole.length >= lgroup + group) {
                pos = whole.length - lgroup;
                for (var i = 0; i < pos; i++) {
                    if ((pos - i) % group === 0 && i !== 0) {
                        formatedText += groupSep
                    }
                    formatedText += whole.charAt(i)
                }
            }
            for (i = pos; i < whole.length; i++) {
                if ((whole.length - i) % lgroup === 0 && i !== 0) {
                    formatedText += groupSep
                }
                formatedText += whole.charAt(i)
            }
            while (fraction.length < fractionSize) {
                fraction += "0"
            }
            if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize)
        } else {
            if (fractionSize > 0 && number > -1 && number < 1) {
                formatedText = number.toFixed(fractionSize)
            }
        }
        parts.push(isNegative ? pattern.negPre: pattern.posPre);
        parts.push(formatedText);
        parts.push(isNegative ? pattern.negSuf: pattern.posSuf);
        return parts.join("")
    }
    function padNumber(num, digits, trim) {
        var neg = "";
        if (num < 0) {
            neg = "-";
            num = -num
        }
        num = "" + num;
        while (num.length < digits) num = "0" + num;
        if (trim) num = num.substr(num.length - digits);
        return neg + num
    }
    function dateGetter(name, size, offset, trim) {
        offset = offset || 0;
        return function(date) {
            var value = date["get" + name]();
            if (offset > 0 || value > -offset) value += offset;
            if (value === 0 && offset == -12) value = 12;
            return padNumber(value, size, trim)
        }
    }
    function dateStrGetter(name, shortForm) {
        return function(date, formats) {
            var value = date["get" + name]();
            var get = uppercase(shortForm ? "SHORT" + name: name);
            return formats[get][value]
        }
    }
    function timeZoneGetter(date) {
        var zone = -1 * date.getTimezoneOffset();
        var paddedZone = zone >= 0 ? "+": "";
        paddedZone += padNumber(Math[zone > 0 ? "floor": "ceil"](zone / 60), 2) + padNumber(Math.abs(zone % 60), 2);
        return paddedZone
    }
    function ampmGetter(date, formats) {
        return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1]
    }
    var DATE_FORMATS = {
        yyyy: dateGetter("FullYear", 4),
        yy: dateGetter("FullYear", 2, 0, true),
        y: dateGetter("FullYear", 1),
        MMMM: dateStrGetter("Month"),
        MMM: dateStrGetter("Month", true),
        MM: dateGetter("Month", 2, 1),
        M: dateGetter("Month", 1, 1),
        dd: dateGetter("Date", 2),
        d: dateGetter("Date", 1),
        HH: dateGetter("Hours", 2),
        H: dateGetter("Hours", 1),
        hh: dateGetter("Hours", 2, -12),
        h: dateGetter("Hours", 1, -12),
        mm: dateGetter("Minutes", 2),
        m: dateGetter("Minutes", 1),
        ss: dateGetter("Seconds", 2),
        s: dateGetter("Seconds", 1),
        sss: dateGetter("Milliseconds", 3),
        EEEE: dateStrGetter("Day"),
        EEE: dateStrGetter("Day", true),
        a: ampmGetter,
        Z: timeZoneGetter
    };
    var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,
    NUMBER_STRING = /^\-?\d+$/;
    dateFilter.$inject = ["$locale"];
    function dateFilter($locale) {
        var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
        function jsonStringToDate(string) {
            var match;
            if (match = string.match(R_ISO8601_STR)) {
                var date = new Date(0),
                tzHour = 0,
                tzMin = 0,
                dateSetter = match[8] ? date.setUTCFullYear: date.setFullYear,
                timeSetter = match[8] ? date.setUTCHours: date.setHours;
                if (match[9]) {
                    tzHour = int(match[9] + match[10]);
                    tzMin = int(match[9] + match[11])
                }
                dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
                var h = int(match[4] || 0) - tzHour;
                var m = int(match[5] || 0) - tzMin;
                var s = int(match[6] || 0);
                var ms = Math.round(parseFloat("0." + (match[7] || 0)) * 1e3);
                timeSetter.call(date, h, m, s, ms);
                return date
            }
            return string
        }
        return function(date, format) {
            var text = "",
            parts = [],
            fn,
            match;
            format = format || "mediumDate";
            format = $locale.DATETIME_FORMATS[format] || format;
            if (isString(date)) {
                if (NUMBER_STRING.test(date)) {
                    date = int(date)
                } else {
                    date = jsonStringToDate(date)
                }
            }
            if (isNumber(date)) {
                date = new Date(date)
            }
            if (!isDate(date)) {
                return date
            }
            while (format) {
                match = DATE_FORMATS_SPLIT.exec(format);
                if (match) {
                    parts = concat(parts, match, 1);
                    format = parts.pop()
                } else {
                    parts.push(format);
                    format = null
                }
            }
            forEach(parts,
            function(value) {
                fn = DATE_FORMATS[value];
                text += fn ? fn(date, $locale.DATETIME_FORMATS) : value.replace(/(^'|'$)/g, "").replace(/''/g, "'")
            });
            return text
        }
    }
    function jsonFilter() {
        return function(object) {
            return toJson(object, true)
        }
    }
    var lowercaseFilter = valueFn(lowercase);
    var uppercaseFilter = valueFn(uppercase);
    function limitToFilter() {
        return function(input, limit) {
            if (!isArray(input) && !isString(input)) return input;
            limit = int(limit);
            if (isString(input)) {
                if (limit) {
                    return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length)
                } else {
                    return ""
                }
            }
            var out = [],
            i,
            n;
            if (limit > input.length) limit = input.length;
            else if (limit < -input.length) limit = -input.length;
            if (limit > 0) {
                i = 0;
                n = limit
            } else {
                i = input.length + limit;
                n = input.length
            }
            for (; i < n; i++) {
                out.push(input[i])
            }
            return out
        }
    }
    orderByFilter.$inject = ["$parse"];
    function orderByFilter($parse) {
        return function(array, sortPredicate, reverseOrder) {
            if (!isArray(array)) return array;
            if (!sortPredicate) return array;
            sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
            sortPredicate = map(sortPredicate,
            function(predicate) {
                var descending = false,
                get = predicate || identity;
                if (isString(predicate)) {
                    if (predicate.charAt(0) == "+" || predicate.charAt(0) == "-") {
                        descending = predicate.charAt(0) == "-";
                        predicate = predicate.substring(1)
                    }
                    get = $parse(predicate)
                }
                return reverseComparator(function(a, b) {
                    return compare(get(a), get(b))
                },
                descending)
            });
            var arrayCopy = [];
            for (var i = 0; i < array.length; i++) {
                arrayCopy.push(array[i])
            }
            return arrayCopy.sort(reverseComparator(comparator, reverseOrder));
            function comparator(o1, o2) {
                for (var i = 0; i < sortPredicate.length; i++) {
                    var comp = sortPredicate[i](o1, o2);
                    if (comp !== 0) return comp
                }
                return 0
            }
            function reverseComparator(comp, descending) {
                return toBoolean(descending) ?
                function(a, b) {
                    return comp(b, a)
                }: comp
            }
            function compare(v1, v2) {
                var t1 = typeof v1;
                var t2 = typeof v2;
                if (t1 == t2) {
                    if (t1 == "string") {
                        v1 = v1.toLowerCase();
                        v2 = v2.toLowerCase()
                    }
                    if (v1 === v2) return 0;
                    return v1 < v2 ? -1 : 1
                } else {
                    return t1 < t2 ? -1 : 1
                }
            }
        }
    }
    function ngDirective(directive) {
        if (isFunction(directive)) {
            directive = {
                link: directive
            }
        }
        directive.restrict = directive.restrict || "AC";
        return valueFn(directive)
    }
    var htmlAnchorDirective = valueFn({
        restrict: "E",
        compile: function(element, attr) {
            if (msie <= 8) {
                if (!attr.href && !attr.name) {
                    attr.$set("href", "")
                }
                element.append(document.createComment("IE fix"))
            }
            return function(scope, element) {
                element.on("click",
                function(event) {
                    if (!element.attr("href")) {
                        event.preventDefault()
                    }
                })
            }
        }
    });
    var ngAttributeAliasDirectives = {};
    forEach(BOOLEAN_ATTR,
    function(propName, attrName) {
        if (propName == "multiple") return;
        var normalized = directiveNormalize("ng-" + attrName);
        ngAttributeAliasDirectives[normalized] = function() {
            return {
                priority: 100,
                compile: function() {
                    return function(scope, element, attr) {
                        scope.$watch(attr[normalized],
                        function ngBooleanAttrWatchAction(value) {
                            attr.$set(attrName, !!value)
                        })
                    }
                }
            }
        }
    });
    forEach(["src", "srcset", "href"],
    function(attrName) {
        var normalized = directiveNormalize("ng-" + attrName);
        ngAttributeAliasDirectives[normalized] = function() {
            return {
                priority: 99,
                link: function(scope, element, attr) {
                    attr.$observe(normalized,
                    function(value) {
                        if (!value) return;
                        attr.$set(attrName, value);
                        if (msie) element.prop(attrName, attr[attrName])
                    })
                }
            }
        }
    });
    var nullFormCtrl = {
        $addControl: noop,
        $removeControl: noop,
        $setValidity: noop,
        $setDirty: noop,
        $setPristine: noop
    };
    FormController.$inject = ["$element", "$attrs", "$scope"];
    function FormController(element, attrs) {
        var form = this,
        parentForm = element.parent().controller("form") || nullFormCtrl,
        invalidCount = 0,
        errors = form.$error = {},
        controls = [];
        form.$name = attrs.name || attrs.ngForm;
        form.$dirty = false;
        form.$pristine = true;
        form.$valid = true;
        form.$invalid = false;
        parentForm.$addControl(form);
        element.addClass(PRISTINE_CLASS);
        toggleValidCss(true);
        function toggleValidCss(isValid, validationErrorKey) {
            validationErrorKey = validationErrorKey ? "-" + snake_case(validationErrorKey, "-") : "";
            element.removeClass((isValid ? INVALID_CLASS: VALID_CLASS) + validationErrorKey).addClass((isValid ? VALID_CLASS: INVALID_CLASS) + validationErrorKey)
        }
        form.$addControl = function(control) {
            assertNotHasOwnProperty(control.$name, "input");
            controls.push(control);
            if (control.$name) {
                form[control.$name] = control
            }
        };
        form.$removeControl = function(control) {
            if (control.$name && form[control.$name] === control) {
                delete form[control.$name]
            }
            forEach(errors,
            function(queue, validationToken) {
                form.$setValidity(validationToken, true, control)
            });
            arrayRemove(controls, control)
        };
        form.$setValidity = function(validationToken, isValid, control) {
            var queue = errors[validationToken];
            if (isValid) {
                if (queue) {
                    arrayRemove(queue, control);
                    if (!queue.length) {
                        invalidCount--;
                        if (!invalidCount) {
                            toggleValidCss(isValid);
                            form.$valid = true;
                            form.$invalid = false
                        }
                        errors[validationToken] = false;
                        toggleValidCss(true, validationToken);
                        parentForm.$setValidity(validationToken, true, form)
                    }
                }
            } else {
                if (!invalidCount) {
                    toggleValidCss(isValid)
                }
                if (queue) {
                    if (includes(queue, control)) return
                } else {
                    errors[validationToken] = queue = [];
                    invalidCount++;
                    toggleValidCss(false, validationToken);
                    parentForm.$setValidity(validationToken, false, form)
                }
                queue.push(control);
                form.$valid = false;
                form.$invalid = true
            }
        };
        form.$setDirty = function() {
            element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
            form.$dirty = true;
            form.$pristine = false;
            parentForm.$setDirty()
        };
        form.$setPristine = function() {
            element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
            form.$dirty = false;
            form.$pristine = true;
            forEach(controls,
            function(control) {
                control.$setPristine()
            })
        }
    }
    var formDirectiveFactory = function(isNgForm) {
        return ["$timeout",
        function($timeout) {
            var formDirective = {
                name: "form",
                restrict: isNgForm ? "EAC": "E",
                controller: FormController,
                compile: function() {
                    return {
                        pre: function(scope, formElement, attr, controller) {
                            if (!attr.action) {
                                var preventDefaultListener = function(event) {
                                    event.preventDefault ? event.preventDefault() : event.returnValue = false
                                };
                                addEventListenerFn(formElement[0], "submit", preventDefaultListener);
                                formElement.on("$destroy",
                                function() {
                                    $timeout(function() {
                                        removeEventListenerFn(formElement[0], "submit", preventDefaultListener)
                                    },
                                    0, false)
                                })
                            }
                            var parentFormCtrl = formElement.parent().controller("form"),
                            alias = attr.name || attr.ngForm;
                            if (alias) {
                                setter(scope, alias, controller, alias)
                            }
                            if (parentFormCtrl) {
                                formElement.on("$destroy",
                                function() {
                                    parentFormCtrl.$removeControl(controller);
                                    if (alias) {
                                        setter(scope, alias, undefined, alias)
                                    }
                                    extend(controller, nullFormCtrl)
                                })
                            }
                        }
                    }
                }
            };
            return formDirective
        }]
    };
    var formDirective = formDirectiveFactory();
    var ngFormDirective = formDirectiveFactory(true);
    var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
    var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/;
    var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
    var inputType = {
        text: textInputType,
        number: numberInputType,
        url: urlInputType,
        email: emailInputType,
        radio: radioInputType,
        checkbox: checkboxInputType,
        hidden: noop,
        button: noop,
        submit: noop,
        reset: noop
    };
    function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
        var listener = function() {
            var value = element.val();
            if (toBoolean(attr.ngTrim || "T")) {
                value = trim(value)
            }
            if (ctrl.$viewValue !== value) {
                scope.$apply(function() {
                    ctrl.$setViewValue(value)
                })
            }
        };
        if ($sniffer.hasEvent("input")) {
            element.on("input", listener)
        } else {
            var timeout;
            var deferListener = function() {
                if (!timeout) {
                    timeout = $browser.defer(function() {
                        listener();
                        timeout = null
                    })
                }
            };
            element.on("keydown",
            function(event) {
                var key = event.keyCode;
                if (key === 91 || 15 < key && key < 19 || 37 <= key && key <= 40) return;
                deferListener()
            });
            element.on("change", listener);
            if ($sniffer.hasEvent("paste")) {
                element.on("paste cut", deferListener)
            }
        }
        ctrl.$render = function() {
            element.val(ctrl.$isEmpty(ctrl.$viewValue) ? "": ctrl.$viewValue)
        };
        var pattern = attr.ngPattern,
        patternValidator, match;
        var validate = function(regexp, value) {
            if (ctrl.$isEmpty(value) || regexp.test(value)) {
                ctrl.$setValidity("pattern", true);
                return value
            } else {
                ctrl.$setValidity("pattern", false);
                return undefined
            }
        };
        if (pattern) {
            match = pattern.match(/^\/(.*)\/([gim]*)$/);
            if (match) {
                pattern = new RegExp(match[1], match[2]);
                patternValidator = function(value) {
                    return validate(pattern, value)
                }
            } else {
                patternValidator = function(value) {
                    var patternObj = scope.$eval(pattern);
                    if (!patternObj || !patternObj.test) {
                        throw minErr("ngPattern")("noregexp", "Expected {0} to be a RegExp but was {1}. Element: {2}", pattern, patternObj, startingTag(element))
                    }
                    return validate(patternObj, value)
                }
            }
            ctrl.$formatters.push(patternValidator);
            ctrl.$parsers.push(patternValidator)
        }
        if (attr.ngMinlength) {
            var minlength = int(attr.ngMinlength);
            var minLengthValidator = function(value) {
                if (!ctrl.$isEmpty(value) && value.length < minlength) {
                    ctrl.$setValidity("minlength", false);
                    return undefined
                } else {
                    ctrl.$setValidity("minlength", true);
                    return value
                }
            };
            ctrl.$parsers.push(minLengthValidator);
            ctrl.$formatters.push(minLengthValidator)
        }
        if (attr.ngMaxlength) {
            var maxlength = int(attr.ngMaxlength);
            var maxLengthValidator = function(value) {
                if (!ctrl.$isEmpty(value) && value.length > maxlength) {
                    ctrl.$setValidity("maxlength", false);
                    return undefined
                } else {
                    ctrl.$setValidity("maxlength", true);
                    return value
                }
            };
            ctrl.$parsers.push(maxLengthValidator);
            ctrl.$formatters.push(maxLengthValidator)
        }
    }
    function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
        textInputType(scope, element, attr, ctrl, $sniffer, $browser);
        ctrl.$parsers.push(function(value) {
            var empty = ctrl.$isEmpty(value);
            if (empty || NUMBER_REGEXP.test(value)) {
                ctrl.$setValidity("number", true);
                return value === "" ? null: empty ? value: parseFloat(value)
            } else {
                ctrl.$setValidity("number", false);
                return undefined
            }
        });
        ctrl.$formatters.push(function(value) {
            return ctrl.$isEmpty(value) ? "": "" + value
        });
        if (attr.min) {
            var min = parseFloat(attr.min);
            var minValidator = function(value) {
                if (!ctrl.$isEmpty(value) && value < min) {
                    ctrl.$setValidity("min", false);
                    return undefined
                } else {
                    ctrl.$setValidity("min", true);
                    return value
                }
            };
            ctrl.$parsers.push(minValidator);
            ctrl.$formatters.push(minValidator)
        }
        if (attr.max) {
            var max = parseFloat(attr.max);
            var maxValidator = function(value) {
                if (!ctrl.$isEmpty(value) && value > max) {
                    ctrl.$setValidity("max", false);
                    return undefined
                } else {
                    ctrl.$setValidity("max", true);
                    return value
                }
            };
            ctrl.$parsers.push(maxValidator);
            ctrl.$formatters.push(maxValidator)
        }
        ctrl.$formatters.push(function(value) {
            if (ctrl.$isEmpty(value) || isNumber(value)) {
                ctrl.$setValidity("number", true);
                return value
            } else {
                ctrl.$setValidity("number", false);
                return undefined
            }
        })
    }
    function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
        textInputType(scope, element, attr, ctrl, $sniffer, $browser);
        var urlValidator = function(value) {
            if (ctrl.$isEmpty(value) || URL_REGEXP.test(value)) {
                ctrl.$setValidity("url", true);
                return value
            } else {
                ctrl.$setValidity("url", false);
                return undefined
            }
        };
        ctrl.$formatters.push(urlValidator);
        ctrl.$parsers.push(urlValidator)
    }
    function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
        textInputType(scope, element, attr, ctrl, $sniffer, $browser);
        var emailValidator = function(value) {
            if (ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value)) {
                ctrl.$setValidity("email", true);
                return value
            } else {
                ctrl.$setValidity("email", false);
                return undefined
            }
        };
        ctrl.$formatters.push(emailValidator);
        ctrl.$parsers.push(emailValidator)
    }
    function radioInputType(scope, element, attr, ctrl) {
        if (isUndefined(attr.name)) {
            element.attr("name", nextUid())
        }
        element.on("click",
        function() {
            if (element[0].checked) {
                scope.$apply(function() {
                    ctrl.$setViewValue(attr.value)
                })
            }
        });
        ctrl.$render = function() {
            var value = attr.value;
            element[0].checked = value == ctrl.$viewValue
        };
        attr.$observe("value", ctrl.$render)
    }
    function checkboxInputType(scope, element, attr, ctrl) {
        var trueValue = attr.ngTrueValue,
        falseValue = attr.ngFalseValue;
        if (!isString(trueValue)) trueValue = true;
        if (!isString(falseValue)) falseValue = false;
        element.on("click",
        function() {
            scope.$apply(function() {
                ctrl.$setViewValue(element[0].checked)
            })
        });
        ctrl.$render = function() {
            element[0].checked = ctrl.$viewValue
        };
        ctrl.$isEmpty = function(value) {
            return value !== trueValue
        };
        ctrl.$formatters.push(function(value) {
            return value === trueValue
        });
        ctrl.$parsers.push(function(value) {
            return value ? trueValue: falseValue
        })
    }
    var inputDirective = ["$browser", "$sniffer",
    function($browser, $sniffer) {
        return {
            restrict: "E",
            require: "?ngModel",
            link: function(scope, element, attr, ctrl) {
                if (ctrl) { (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrl, $sniffer, $browser)
                }
            }
        }
    }];
    var VALID_CLASS = "ng-valid",
    INVALID_CLASS = "ng-invalid",
    PRISTINE_CLASS = "ng-pristine",
    DIRTY_CLASS = "ng-dirty";
    var NgModelController = ["$scope", "$exceptionHandler", "$attrs", "$element", "$parse",
    function($scope, $exceptionHandler, $attr, $element, $parse) {
        this.$viewValue = Number.NaN;
        this.$modelValue = Number.NaN;
        this.$parsers = [];
        this.$formatters = [];
        this.$viewChangeListeners = [];
        this.$pristine = true;
        this.$dirty = false;
        this.$valid = true;
        this.$invalid = false;
        this.$name = $attr.name;
        var ngModelGet = $parse($attr.ngModel),
        ngModelSet = ngModelGet.assign;
        if (!ngModelSet) {
            throw minErr("ngModel")("nonassign", "Expression '{0}' is non-assignable. Element: {1}", $attr.ngModel, startingTag($element))
        }
        this.$render = noop;
        this.$isEmpty = function(value) {
            return isUndefined(value) || value === "" || value === null || value !== value
        };
        var parentForm = $element.inheritedData("$formController") || nullFormCtrl,
        invalidCount = 0,
        $error = this.$error = {};
        $element.addClass(PRISTINE_CLASS);
        toggleValidCss(true);
        function toggleValidCss(isValid, validationErrorKey) {
            validationErrorKey = validationErrorKey ? "-" + snake_case(validationErrorKey, "-") : "";
            $element.removeClass((isValid ? INVALID_CLASS: VALID_CLASS) + validationErrorKey).addClass((isValid ? VALID_CLASS: INVALID_CLASS) + validationErrorKey)
        }
        this.$setValidity = function(validationErrorKey, isValid) {
            if ($error[validationErrorKey] === !isValid) return;
            if (isValid) {
                if ($error[validationErrorKey]) invalidCount--;
                if (!invalidCount) {
                    toggleValidCss(true);
                    this.$valid = true;
                    this.$invalid = false
                }
            } else {
                toggleValidCss(false);
                this.$invalid = true;
                this.$valid = false;
                invalidCount++
            }
            $error[validationErrorKey] = !isValid;
            toggleValidCss(isValid, validationErrorKey);
            parentForm.$setValidity(validationErrorKey, isValid, this)
        };
        this.$setPristine = function() {
            this.$dirty = false;
            this.$pristine = true;
            $element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS)
        };
        this.$setViewValue = function(value) {
            this.$viewValue = value;
            if (this.$pristine) {
                this.$dirty = true;
                this.$pristine = false;
                $element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
                parentForm.$setDirty()
            }
            forEach(this.$parsers,
            function(fn) {
                value = fn(value)
            });
            if (this.$modelValue !== value) {
                this.$modelValue = value;
                ngModelSet($scope, value);
                forEach(this.$viewChangeListeners,
                function(listener) {
                    try {
                        listener()
                    } catch(e) {
                        $exceptionHandler(e)
                    }
                })
            }
        };
        var ctrl = this;
        $scope.$watch(function ngModelWatch() {
            var value = ngModelGet($scope);
            if (ctrl.$modelValue !== value) {
                var formatters = ctrl.$formatters,
                idx = formatters.length;
                ctrl.$modelValue = value;
                while (idx--) {
                    value = formatters[idx](value)
                }
                if (ctrl.$viewValue !== value) {
                    ctrl.$viewValue = value;
                    ctrl.$render()
                }
            }
        })
    }];
    var ngModelDirective = function() {
        return {
            require: ["ngModel", "^?form"],
            controller: NgModelController,
            link: function(scope, element, attr, ctrls) {
                var modelCtrl = ctrls[0],
                formCtrl = ctrls[1] || nullFormCtrl;
                formCtrl.$addControl(modelCtrl);
                element.on("$destroy",
                function() {
                    formCtrl.$removeControl(modelCtrl)
                })
            }
        }
    };
    var ngChangeDirective = valueFn({
        require: "ngModel",
        link: function(scope, element, attr, ctrl) {
            ctrl.$viewChangeListeners.push(function() {
                scope.$eval(attr.ngChange)
            })
        }
    });
    var requiredDirective = function() {
        return {
            require: "?ngModel",
            link: function(scope, elm, attr, ctrl) {
                if (!ctrl) return;
                attr.required = true;
                var validator = function(value) {
                    if (attr.required && ctrl.$isEmpty(value)) {
                        ctrl.$setValidity("required", false);
                        return
                    } else {
                        ctrl.$setValidity("required", true);
                        return value
                    }
                };
                ctrl.$formatters.push(validator);
                ctrl.$parsers.unshift(validator);
                attr.$observe("required",
                function() {
                    validator(ctrl.$viewValue)
                })
            }
        }
    };
    var ngListDirective = function() {
        return {
            require: "ngModel",
            link: function(scope, element, attr, ctrl) {
                var match = /\/(.*)\//.exec(attr.ngList),
                separator = match && new RegExp(match[1]) || attr.ngList || ",";
                var parse = function(viewValue) {
                    if (isUndefined(viewValue)) return;
                    var list = [];
                    if (viewValue) {
                        forEach(viewValue.split(separator),
                        function(value) {
                            if (value) list.push(trim(value))
                        })
                    }
                    return list
                };
                ctrl.$parsers.push(parse);
                ctrl.$formatters.push(function(value) {
                    if (isArray(value)) {
                        return value.join(", ")
                    }
                    return undefined
                });
                ctrl.$isEmpty = function(value) {
                    return ! value || !value.length
                }
            }
        }
    };
    var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
    var ngValueDirective = function() {
        return {
            priority: 100,
            compile: function(tpl, tplAttr) {
                if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
                    return function ngValueConstantLink(scope, elm, attr) {
                        attr.$set("value", scope.$eval(attr.ngValue))
                    }
                } else {
                    return function ngValueLink(scope, elm, attr) {
                        scope.$watch(attr.ngValue,
                        function valueWatchAction(value) {
                            attr.$set("value", value)
                        })
                    }
                }
            }
        }
    };
    var ngBindDirective = ngDirective(function(scope, element, attr) {
        element.addClass("ng-binding").data("$binding", attr.ngBind);
        scope.$watch(attr.ngBind,
        function ngBindWatchAction(value) {
            element.text(value == undefined ? "": value)
        })
    });
    var ngBindTemplateDirective = ["$interpolate",
    function($interpolate) {
        return function(scope, element, attr) {
            var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate));
            element.addClass("ng-binding").data("$binding", interpolateFn);
            attr.$observe("ngBindTemplate",
            function(value) {
                element.text(value)
            })
        }
    }];
    var ngBindHtmlDirective = ["$sce", "$parse",
    function($sce, $parse) {
        return function(scope, element, attr) {
            element.addClass("ng-binding").data("$binding", attr.ngBindHtml);
            var parsed = $parse(attr.ngBindHtml);
            function getStringValue() {
                return (parsed(scope) || "").toString()
            }
            scope.$watch(getStringValue,
            function ngBindHtmlWatchAction(value) {
                element.html($sce.getTrustedHtml(parsed(scope)) || "")
            })
        }
    }];
    function classDirective(name, selector) {
        name = "ngClass" + name;
        return function() {
            return {
                restrict: "AC",
                link: function(scope, element, attr) {
                    var oldVal = undefined;
                    scope.$watch(attr[name], ngClassWatchAction, true);
                    attr.$observe("class",
                    function(value) {
                        ngClassWatchAction(scope.$eval(attr[name]))
                    });
                    if (name !== "ngClass") {
                        scope.$watch("$index",
                        function($index, old$index) {
                            var mod = $index & 1;
                            if (mod !== old$index & 1) {
                                if (mod === selector) {
                                    addClass(scope.$eval(attr[name]))
                                } else {
                                    removeClass(scope.$eval(attr[name]))
                                }
                            }
                        })
                    }
                    function ngClassWatchAction(newVal) {
                        if (selector === true || scope.$index % 2 === selector) {
                            if (oldVal && !equals(newVal, oldVal)) {
                                removeClass(oldVal)
                            }
                            addClass(newVal)
                        }
                        oldVal = copy(newVal)
                    }
                    function removeClass(classVal) {
                        attr.$removeClass(flattenClasses(classVal))
                    }
                    function addClass(classVal) {
                        attr.$addClass(flattenClasses(classVal))
                    }
                    function flattenClasses(classVal) {
                        if (isArray(classVal)) {
                            return classVal.join(" ")
                        } else if (isObject(classVal)) {
                            var classes = [],
                            i = 0;
                            forEach(classVal,
                            function(v, k) {
                                if (v) {
                                    classes.push(k)
                                }
                            });
                            return classes.join(" ")
                        }
                        return classVal
                    }
                }
            }
        }
    }
    var ngClassDirective = classDirective("", true);
    var ngClassOddDirective = classDirective("Odd", 0);
    var ngClassEvenDirective = classDirective("Even", 1);
    var ngCloakDirective = ngDirective({
        compile: function(element, attr) {
            attr.$set("ngCloak", undefined);
            element.removeClass("ng-cloak")
        }
    });
    var ngControllerDirective = [function() {
        return {
            scope: true,
            controller: "@"
        }
    }];
    var ngCspDirective = ["$sniffer",
    function($sniffer) {
        return {
            priority: 1e3,
            compile: function() {
                $sniffer.csp = true
            }
        }
    }];
    var ngEventDirectives = {};
    forEach("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),
    function(name) {
        var directiveName = directiveNormalize("ng-" + name);
        ngEventDirectives[directiveName] = ["$parse",
        function($parse) {
            return function(scope, element, attr) {
                var fn = $parse(attr[directiveName]);
                element.on(lowercase(name),
                function(event) {
                    scope.$apply(function() {
                        fn(scope, {
                            $event: event
                        })
                    })
                })
            }
        }]
    });
    var ngIfDirective = ["$animate",
    function($animate) {
        return {
            transclude: "element",
            priority: 600,
            terminal: true,
            restrict: "A",
            compile: function(element, attr, transclude) {
                return function($scope, $element, $attr) {
                    var childElement, childScope;
                    $scope.$watch($attr.ngIf,
                    function ngIfWatchAction(value) {
                        if (childElement) {
                            $animate.leave(childElement);
                            childElement = undefined
                        }
                        if (childScope) {
                            childScope.$destroy();
                            childScope = undefined
                        }
                        if (toBoolean(value)) {
                            childScope = $scope.$new();
                            transclude(childScope,
                            function(clone) {
                                childElement = clone;
                                $animate.enter(clone, $element.parent(), $element)
                            })
                        }
                    })
                }
            }
        }
    }];
    var ngIncludeDirective = ["$http", "$templateCache", "$anchorScroll", "$compile", "$animate", "$sce",
    function($http, $templateCache, $anchorScroll, $compile, $animate, $sce) {
        return {
            restrict: "ECA",
            priority: 400,
            terminal: true,
            transclude: "element",
            compile: function(element, attr, transclusion) {
                var srcExp = attr.ngInclude || attr.src,
                onloadExp = attr.onload || "",
                autoScrollExp = attr.autoscroll;
                return function(scope, $element) {
                    var changeCounter = 0,
                    currentScope, currentElement;
                    var cleanupLastIncludeContent = function() {
                        if (currentScope) {
                            currentScope.$destroy();
                            currentScope = null
                        }
                        if (currentElement) {
                            $animate.leave(currentElement);
                            currentElement = null
                        }
                    };
                    scope.$watch($sce.parseAsResourceUrl(srcExp),
                    function ngIncludeWatchAction(src) {
                        var thisChangeId = ++changeCounter;
                        if (src) {
                            $http.get(src, {
                                cache: $templateCache
                            }).success(function(response) {
                                if (thisChangeId !== changeCounter) return;
                                var newScope = scope.$new();
                                transclusion(newScope,
                                function(clone) {
                                    cleanupLastIncludeContent();
                                    currentScope = newScope;
                                    currentElement = clone;
                                    currentElement.html(response);
                                    $animate.enter(currentElement, null, $element);
                                    $compile(currentElement.contents())(currentScope);
                                    if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
                                        $anchorScroll()
                                    }
                                    currentScope.$emit("$includeContentLoaded");
                                    scope.$eval(onloadExp)
                                })
                            }).error(function() {
                                if (thisChangeId === changeCounter) cleanupLastIncludeContent()
                            });
                            scope.$emit("$includeContentRequested")
                        } else {
                            cleanupLastIncludeContent()
                        }
                    })
                }
            }
        }
    }];
    var ngInitDirective = ngDirective({
        compile: function() {
            return {
                pre: function(scope, element, attrs) {
                    scope.$eval(attrs.ngInit)
                }
            }
        }
    });
    var ngNonBindableDirective = ngDirective({
        terminal: true,
        priority: 1e3
    });
    var ngPluralizeDirective = ["$locale", "$interpolate",
    function($locale, $interpolate) {
        var BRACE = /{}/g;
        return {
            restrict: "EA",
            link: function(scope, element, attr) {
                var numberExp = attr.count,
                whenExp = attr.$attr.when && element.attr(attr.$attr.when),
                offset = attr.offset || 0,
                whens = scope.$eval(whenExp) || {},
                whensExpFns = {},
                startSymbol = $interpolate.startSymbol(),
                endSymbol = $interpolate.endSymbol(),
                isWhen = /^when(Minus)?(.+)$/;
                forEach(attr,
                function(expression, attributeName) {
                    if (isWhen.test(attributeName)) {
                        whens[lowercase(attributeName.replace("when", "").replace("Minus", "-"))] = element.attr(attr.$attr[attributeName])
                    }
                });
                forEach(whens,
                function(expression, key) {
                    whensExpFns[key] = $interpolate(expression.replace(BRACE, startSymbol + numberExp + "-" + offset + endSymbol))
                });
                scope.$watch(function ngPluralizeWatch() {
                    var value = parseFloat(scope.$eval(numberExp));
                    if (!isNaN(value)) {
                        if (! (value in whens)) value = $locale.pluralCat(value - offset);
                        return whensExpFns[value](scope, element, true)
                    } else {
                        return ""
                    }
                },
                function ngPluralizeWatchAction(newVal) {
                    element.text(newVal)
                })
            }
        }
    }];
    var ngRepeatDirective = ["$parse", "$animate",
    function($parse, $animate) {
        var NG_REMOVED = "$$NG_REMOVED";
        var ngRepeatMinErr = minErr("ngRepeat");
        return {
            transclude: "element",
            priority: 1e3,
            terminal: true,
            compile: function(element, attr, linker) {
                return function($scope, $element, $attr) {
                    var expression = $attr.ngRepeat;
                    var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
                    trackByExp,
                    trackByExpGetter,
                    trackByIdExpFn,
                    trackByIdArrayFn,
                    trackByIdObjFn,
                    lhs,
                    rhs,
                    valueIdentifier,
                    keyIdentifier,
                    hashFnLocals = {
                        $id: hashKey
                    };
                    if (!match) {
                        throw ngRepeatMinErr("iexp", "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.", expression)
                    }
                    lhs = match[1];
                    rhs = match[2];
                    trackByExp = match[4];
                    if (trackByExp) {
                        trackByExpGetter = $parse(trackByExp);
                        trackByIdExpFn = function(key, value, index) {
                            if (keyIdentifier) hashFnLocals[keyIdentifier] = key;
                            hashFnLocals[valueIdentifier] = value;
                            hashFnLocals.$index = index;
                            return trackByExpGetter($scope, hashFnLocals)
                        }
                    } else {
                        trackByIdArrayFn = function(key, value) {
                            return hashKey(value)
                        };
                        trackByIdObjFn = function(key) {
                            return key
                        }
                    }
                    match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);
                    if (!match) {
                        throw ngRepeatMinErr("iidexp", "'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.", lhs)
                    }
                    valueIdentifier = match[3] || match[1];
                    keyIdentifier = match[2];
                    var lastBlockMap = {};
                    $scope.$watchCollection(rhs,
                    function ngRepeatAction(collection) {
                        var index, length, previousNode = $element[0],
                        nextNode,
                        nextBlockMap = {},
                        arrayLength,
                        childScope,
                        key,
                        value,
                        trackById,
                        trackByIdFn,
                        collectionKeys,
                        block,
                        nextBlockOrder = [],
                        elementsToRemove;
                        if (isArrayLike(collection)) {
                            collectionKeys = collection;
                            trackByIdFn = trackByIdExpFn || trackByIdArrayFn
                        } else {
                            trackByIdFn = trackByIdExpFn || trackByIdObjFn;
                            collectionKeys = [];
                            for (key in collection) {
                                if (collection.hasOwnProperty(key) && key.charAt(0) != "$") {
                                    collectionKeys.push(key)
                                }
                            }
                            collectionKeys.sort()
                        }
                        arrayLength = collectionKeys.length;
                        length = nextBlockOrder.length = collectionKeys.length;
                        for (index = 0; index < length; index++) {
                            key = collection === collectionKeys ? index: collectionKeys[index];
                            value = collection[key];
                            trackById = trackByIdFn(key, value, index);
                            assertNotHasOwnProperty(trackById, "`track by` id");
                            if (lastBlockMap.hasOwnProperty(trackById)) {
                                block = lastBlockMap[trackById];
                                delete lastBlockMap[trackById];
                                nextBlockMap[trackById] = block;
                                nextBlockOrder[index] = block
                            } else if (nextBlockMap.hasOwnProperty(trackById)) {
                                forEach(nextBlockOrder,
                                function(block) {
                                    if (block && block.startNode) lastBlockMap[block.id] = block
                                });
                                throw ngRepeatMinErr("dupes", "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}", expression, trackById)
                            } else {
                                nextBlockOrder[index] = {
                                    id: trackById
                                };
                                nextBlockMap[trackById] = false
                            }
                        }
                        for (key in lastBlockMap) {
                            if (lastBlockMap.hasOwnProperty(key)) {
                                block = lastBlockMap[key];
                                elementsToRemove = getBlockElements(block);
                                $animate.leave(elementsToRemove);
                                forEach(elementsToRemove,
                                function(element) {
                                    element[NG_REMOVED] = true
                                });
                                block.scope.$destroy()
                            }
                        }
                        for (index = 0, length = collectionKeys.length; index < length; index++) {
                            key = collection === collectionKeys ? index: collectionKeys[index];
                            value = collection[key];
                            block = nextBlockOrder[index];
                            if (nextBlockOrder[index - 1]) previousNode = nextBlockOrder[index - 1].endNode;
                            if (block.startNode) {
                                childScope = block.scope;
                                nextNode = previousNode;
                                do {
                                    nextNode = nextNode.nextSibling
                                } while ( nextNode && nextNode [ NG_REMOVED ]);
                                if (block.startNode == nextNode) {} else {
                                    $animate.move(getBlockElements(block), null, jqLite(previousNode))
                                }
                                previousNode = block.endNode
                            } else {
                                childScope = $scope.$new()
                            }
                            childScope[valueIdentifier] = value;
                            if (keyIdentifier) childScope[keyIdentifier] = key;
                            childScope.$index = index;
                            childScope.$first = index === 0;
                            childScope.$last = index === arrayLength - 1;
                            childScope.$middle = !(childScope.$first || childScope.$last);
                            childScope.$odd = !(childScope.$even = index % 2 == 0);
                            if (!block.startNode) {
                                linker(childScope,
                                function(clone) {
                                    clone[clone.length++] = document.createComment(" end ngRepeat: " + expression + " ");
                                    $animate.enter(clone, null, jqLite(previousNode));
                                    previousNode = clone;
                                    block.scope = childScope;
                                    block.startNode = previousNode && previousNode.endNode ? previousNode.endNode: clone[0];
                                    block.endNode = clone[clone.length - 1];
                                    nextBlockMap[block.id] = block
                                })
                            }
                        }
                        lastBlockMap = nextBlockMap
                    })
                }
            }
        };
        function getBlockElements(block) {
            if (block.startNode === block.endNode) {
                return jqLite(block.startNode)
            }
            var element = block.startNode;
            var elements = [element];
            do {
                element = element.nextSibling;
                if (!element) break;
                elements.push(element)
            } while ( element !== block . endNode );
            return jqLite(elements)
        }
    }];
    var ngShowDirective = ["$animate",
    function($animate) {
        return function(scope, element, attr) {
            scope.$watch(attr.ngShow,
            function ngShowWatchAction(value) {
                $animate[toBoolean(value) ? "removeClass": "addClass"](element, "ng-hide")
            })
        }
    }];
    var ngHideDirective = ["$animate",
    function($animate) {
        return function(scope, element, attr) {
            scope.$watch(attr.ngHide,
            function ngHideWatchAction(value) {
                $animate[toBoolean(value) ? "addClass": "removeClass"](element, "ng-hide")
            })
        }
    }];
    var ngStyleDirective = ngDirective(function(scope, element, attr) {
        scope.$watch(attr.ngStyle,
        function ngStyleWatchAction(newStyles, oldStyles) {
            if (oldStyles && newStyles !== oldStyles) {
                forEach(oldStyles,
                function(val, style) {
                    element.css(style, "")
                })
            }
            if (newStyles) element.css(newStyles)
        },
        true)
    });
    var ngSwitchDirective = ["$animate",
    function($animate) {
        return {
            restrict: "EA",
            require: "ngSwitch",
            controller: ["$scope",
            function ngSwitchController() {
                this.cases = {}
            }],
            link: function(scope, element, attr, ngSwitchController) {
                var watchExpr = attr.ngSwitch || attr.on,
                selectedTranscludes, selectedElements, selectedScopes = [];
                scope.$watch(watchExpr,
                function ngSwitchWatchAction(value) {
                    for (var i = 0,
                    ii = selectedScopes.length; i < ii; i++) {
                        selectedScopes[i].$destroy();
                        $animate.leave(selectedElements[i])
                    }
                    selectedElements = [];
                    selectedScopes = [];
                    if (selectedTranscludes = ngSwitchController.cases["!" + value] || ngSwitchController.cases["?"]) {
                        scope.$eval(attr.change);
                        forEach(selectedTranscludes,
                        function(selectedTransclude) {
                            var selectedScope = scope.$new();
                            selectedScopes.push(selectedScope);
                            selectedTransclude.transclude(selectedScope,
                            function(caseElement) {
                                var anchor = selectedTransclude.element;
                                selectedElements.push(caseElement);
                                $animate.enter(caseElement, anchor.parent(), anchor)
                            })
                        })
                    }
                })
            }
        }
    }];
    var ngSwitchWhenDirective = ngDirective({
        transclude: "element",
        priority: 800,
        require: "^ngSwitch",
        compile: function(element, attrs, transclude) {
            return function(scope, element, attr, ctrl) {
                ctrl.cases["!" + attrs.ngSwitchWhen] = ctrl.cases["!" + attrs.ngSwitchWhen] || [];
                ctrl.cases["!" + attrs.ngSwitchWhen].push({
                    transclude: transclude,
                    element: element
                })
            }
        }
    });
    var ngSwitchDefaultDirective = ngDirective({
        transclude: "element",
        priority: 800,
        require: "^ngSwitch",
        compile: function(element, attrs, transclude) {
            return function(scope, element, attr, ctrl) {
                ctrl.cases["?"] = ctrl.cases["?"] || [];
                ctrl.cases["?"].push({
                    transclude: transclude,
                    element: element
                })
            }
        }
    });
    var ngTranscludeDirective = ngDirective({
        controller: ["$element", "$transclude",
        function($element, $transclude) {
            if (!$transclude) {
                throw minErr("ngTransclude")("orphan", "Illegal use of ngTransclude directive in the template! " + "No parent directive that requires a transclusion found. " + "Element: {0}", startingTag($element))
            }
            this.$transclude = $transclude
        }],
        link: function($scope, $element, $attrs, controller) {
            controller.$transclude(function(clone) {
                $element.html("");
                $element.append(clone)
            })
        }
    });
    var scriptDirective = ["$templateCache",
    function($templateCache) {
        return {
            restrict: "E",
            terminal: true,
            compile: function(element, attr) {
                if (attr.type == "text/ng-template") {
                    var templateUrl = attr.id,
                    text = element[0].text;
                    $templateCache.put(templateUrl, text)
                }
            }
        }
    }];
    var ngOptionsMinErr = minErr("ngOptions");
    var ngOptionsDirective = valueFn({
        terminal: true
    });
    var selectDirective = ["$compile", "$parse",
    function($compile, $parse) {
        var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/,
        nullModelCtrl = {
            $setViewValue: noop
        };
        return {
            restrict: "E",
            require: ["select", "?ngModel"],
            controller: ["$element", "$scope", "$attrs",
            function($element, $scope, $attrs) {
                var self = this,
                optionsMap = {},
                ngModelCtrl = nullModelCtrl,
                nullOption, unknownOption;
                self.databound = $attrs.ngModel;
                self.init = function(ngModelCtrl_, nullOption_, unknownOption_) {
                    ngModelCtrl = ngModelCtrl_;
                    nullOption = nullOption_;
                    unknownOption = unknownOption_
                };
                self.addOption = function(value) {
                    assertNotHasOwnProperty(value, '"option value"');
                    optionsMap[value] = true;
                    if (ngModelCtrl.$viewValue == value) {
                        $element.val(value);
                        if (unknownOption.parent()) unknownOption.remove()
                    }
                };
                self.removeOption = function(value) {
                    if (this.hasOption(value)) {
                        delete optionsMap[value];
                        if (ngModelCtrl.$viewValue == value) {
                            this.renderUnknownOption(value)
                        }
                    }
                };
                self.renderUnknownOption = function(val) {
                    var unknownVal = "? " + hashKey(val) + " ?";
                    unknownOption.val(unknownVal);
                    $element.prepend(unknownOption);
                    $element.val(unknownVal);
                    unknownOption.prop("selected", true)
                };
                self.hasOption = function(value) {
                    return optionsMap.hasOwnProperty(value)
                };
                $scope.$on("$destroy",
                function() {
                    self.renderUnknownOption = noop
                })
            }],
            link: function(scope, element, attr, ctrls) {
                if (!ctrls[1]) return;
                var selectCtrl = ctrls[0],
                ngModelCtrl = ctrls[1],
                multiple = attr.multiple,
                optionsExp = attr.ngOptions,
                nullOption = false,
                emptyOption,
                optionTemplate = jqLite(document.createElement("option")),
                optGroupTemplate = jqLite(document.createElement("optgroup")),
                unknownOption = optionTemplate.clone();
                for (var i = 0,
                children = element.children(), ii = children.length; i < ii; i++) {
                    if (children[i].value == "") {
                        emptyOption = nullOption = children.eq(i);
                        break
                    }
                }
                selectCtrl.init(ngModelCtrl, nullOption, unknownOption);
                if (multiple && (attr.required || attr.ngRequired)) {
                    var requiredValidator = function(value) {
                        ngModelCtrl.$setValidity("required", !attr.required || value && value.length);
                        return value
                    };
                    ngModelCtrl.$parsers.push(requiredValidator);
                    ngModelCtrl.$formatters.unshift(requiredValidator);
                    attr.$observe("required",
                    function() {
                        requiredValidator(ngModelCtrl.$viewValue)
                    })
                }
                if (optionsExp) Options(scope, element, ngModelCtrl);
                else if (multiple) Multiple(scope, element, ngModelCtrl);
                else Single(scope, element, ngModelCtrl, selectCtrl);
                function Single(scope, selectElement, ngModelCtrl, selectCtrl) {
                    ngModelCtrl.$render = function() {
                        var viewValue = ngModelCtrl.$viewValue;
                        if (selectCtrl.hasOption(viewValue)) {
                            if (unknownOption.parent()) unknownOption.remove();
                            selectElement.val(viewValue);
                            if (viewValue === "") emptyOption.prop("selected", true)
                        } else {
                            if (isUndefined(viewValue) && emptyOption) {
                                selectElement.val("")
                            } else {
                                selectCtrl.renderUnknownOption(viewValue)
                            }
                        }
                    };
                    selectElement.on("change",
                    function() {
                        scope.$apply(function() {
                            if (unknownOption.parent()) unknownOption.remove();
                            ngModelCtrl.$setViewValue(selectElement.val())
                        })
                    })
                }
                function Multiple(scope, selectElement, ctrl) {
                    var lastView;
                    ctrl.$render = function() {
                        var items = new HashMap(ctrl.$viewValue);
                        forEach(selectElement.find("option"),
                        function(option) {
                            option.selected = isDefined(items.get(option.value))
                        })
                    };
                    scope.$watch(function selectMultipleWatch() {
                        if (!equals(lastView, ctrl.$viewValue)) {
                            lastView = copy(ctrl.$viewValue);
                            ctrl.$render()
                        }
                    });
                    selectElement.on("change",
                    function() {
                        scope.$apply(function() {
                            var array = [];
                            forEach(selectElement.find("option"),
                            function(option) {
                                if (option.selected) {
                                    array.push(option.value)
                                }
                            });
                            ctrl.$setViewValue(array)
                        })
                    })
                }
                function Options(scope, selectElement, ctrl) {
                    var match;
                    if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) {
                        throw ngOptionsMinErr("iexp", "Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}", optionsExp, startingTag(selectElement))
                    }
                    var displayFn = $parse(match[2] || match[1]),
                    valueName = match[4] || match[6],
                    keyName = match[5],
                    groupByFn = $parse(match[3] || ""),
                    valueFn = $parse(match[2] ? match[1] : valueName),
                    valuesFn = $parse(match[7]),
                    track = match[8],
                    trackFn = track ? $parse(match[8]) : null,
                    optionGroupsCache = [[{
                        element: selectElement,
                        label: ""
                    }]];
                    if (nullOption) {
                        $compile(nullOption)(scope);
                        nullOption.removeClass("ng-scope");
                        nullOption.remove()
                    }
                    selectElement.html("");
                    selectElement.on("change",
                    function() {
                        scope.$apply(function() {
                            var optionGroup, collection = valuesFn(scope) || [],
                            locals = {},
                            key,
                            value,
                            optionElement,
                            index,
                            groupIndex,
                            length,
                            groupLength,
                            trackIndex;
                            if (multiple) {
                                value = [];
                                for (groupIndex = 0, groupLength = optionGroupsCache.length; groupIndex < groupLength; groupIndex++) {
                                    optionGroup = optionGroupsCache[groupIndex];
                                    for (index = 1, length = optionGroup.length; index < length; index++) {
                                        if ((optionElement = optionGroup[index].element)[0].selected) {
                                            key = optionElement.val();
                                            if (keyName) locals[keyName] = key;
                                            if (trackFn) {
                                                for (trackIndex = 0; trackIndex < collection.length; trackIndex++) {
                                                    locals[valueName] = collection[trackIndex];
                                                    if (trackFn(scope, locals) == key) break
                                                }
                                            } else {
                                                locals[valueName] = collection[key]
                                            }
                                            value.push(valueFn(scope, locals))
                                        }
                                    }
                                }
                            } else {
                                key = selectElement.val();
                                if (key == "?") {
                                    value = undefined
                                } else if (key == "") {
                                    value = null
                                } else {
                                    if (trackFn) {
                                        for (trackIndex = 0; trackIndex < collection.length; trackIndex++) {
                                            locals[valueName] = collection[trackIndex];
                                            if (trackFn(scope, locals) == key) {
                                                value = valueFn(scope, locals);
                                                break
                                            }
                                        }
                                    } else {
                                        locals[valueName] = collection[key];
                                        if (keyName) locals[keyName] = key;
                                        value = valueFn(scope, locals)
                                    }
                                }
                            }
                            ctrl.$setViewValue(value)
                        })
                    });
                    ctrl.$render = render;
                    scope.$watch(render);
                    function render() {
                        var optionGroups = {
                            "": []
                        },
                        optionGroupNames = [""],
                        optionGroupName,
                        optionGroup,
                        option,
                        existingParent,
                        existingOptions,
                        existingOption,
                        modelValue = ctrl.$modelValue,
                        values = valuesFn(scope) || [],
                        keys = keyName ? sortedKeys(values) : values,
                        key,
                        groupLength,
                        length,
                        groupIndex,
                        index,
                        locals = {},
                        selected,
                        selectedSet = false,
                        lastElement,
                        element,
                        label;
                        if (multiple) {
                            if (trackFn && isArray(modelValue)) {
                                selectedSet = new HashMap([]);
                                for (var trackIndex = 0; trackIndex < modelValue.length; trackIndex++) {
                                    locals[valueName] = modelValue[trackIndex];
                                    selectedSet.put(trackFn(scope, locals), modelValue[trackIndex])
                                }
                            } else {
                                selectedSet = new HashMap(modelValue)
                            }
                        }
                        for (index = 0; length = keys.length, index < length; index++) {
                            key = index;
                            if (keyName) {
                                key = keys[index];
                                if (key.charAt(0) === "$") continue;
                                locals[keyName] = key
                            }
                            locals[valueName] = values[key];
                            optionGroupName = groupByFn(scope, locals) || "";
                            if (! (optionGroup = optionGroups[optionGroupName])) {
                                optionGroup = optionGroups[optionGroupName] = [];
                                optionGroupNames.push(optionGroupName)
                            }
                            if (multiple) {
                                selected = selectedSet.remove(trackFn ? trackFn(scope, locals) : valueFn(scope, locals)) !== undefined
                            } else {
                                if (trackFn) {
                                    var modelCast = {};
                                    modelCast[valueName] = modelValue;
                                    selected = trackFn(scope, modelCast) === trackFn(scope, locals)
                                } else {
                                    selected = modelValue === valueFn(scope, locals)
                                }
                                selectedSet = selectedSet || selected
                            }
                            label = displayFn(scope, locals);
                            label = label === undefined ? "": label;
                            optionGroup.push({
                                id: trackFn ? trackFn(scope, locals) : keyName ? keys[index] : index,
                                label: label,
                                selected: selected
                            })
                        }
                        if (!multiple) {
                            if (nullOption || modelValue === null) {
                                optionGroups[""].unshift({
                                    id: "",
                                    label: "",
                                    selected: !selectedSet
                                })
                            } else if (!selectedSet) {
                                optionGroups[""].unshift({
                                    id: "?",
                                    label: "",
                                    selected: true
                                })
                            }
                        }
                        for (groupIndex = 0, groupLength = optionGroupNames.length; groupIndex < groupLength; groupIndex++) {
                            optionGroupName = optionGroupNames[groupIndex];
                            optionGroup = optionGroups[optionGroupName];
                            if (optionGroupsCache.length <= groupIndex) {
                                existingParent = {
                                    element: optGroupTemplate.clone().attr("label", optionGroupName),
                                    label: optionGroup.label
                                };
                                existingOptions = [existingParent];
                                optionGroupsCache.push(existingOptions);
                                selectElement.append(existingParent.element)
                            } else {
                                existingOptions = optionGroupsCache[groupIndex];
                                existingParent = existingOptions[0];
                                if (existingParent.label != optionGroupName) {
                                    existingParent.element.attr("label", existingParent.label = optionGroupName)
                                }
                            }
                            lastElement = null;
                            for (index = 0, length = optionGroup.length; index < length; index++) {
                                option = optionGroup[index];
                                if (existingOption = existingOptions[index + 1]) {
                                    lastElement = existingOption.element;
                                    if (existingOption.label !== option.label) {
                                        lastElement.text(existingOption.label = option.label)
                                    }
                                    if (existingOption.id !== option.id) {
                                        lastElement.val(existingOption.id = option.id)
                                    }
                                    if (lastElement[0].selected !== option.selected) {
                                        lastElement.prop("selected", existingOption.selected = option.selected)
                                    }
                                } else {
                                    if (option.id === "" && nullOption) {
                                        element = nullOption
                                    } else { (element = optionTemplate.clone()).val(option.id).attr("selected", option.selected).text(option.label)
                                    }
                                    existingOptions.push(existingOption = {
                                        element: element,
                                        label: option.label,
                                        id: option.id,
                                        selected: option.selected
                                    });
                                    if (lastElement) {
                                        lastElement.after(element)
                                    } else {
                                        existingParent.element.append(element)
                                    }
                                    lastElement = element
                                }
                            }
                            index++;
                            while (existingOptions.length > index) {
                                existingOptions.pop().element.remove()
                            }
                        }
                        while (optionGroupsCache.length > groupIndex) {
                            optionGroupsCache.pop()[0].element.remove()
                        }
                    }
                }
            }
        }
    }];
    var optionDirective = ["$interpolate",
    function($interpolate) {
        var nullSelectCtrl = {
            addOption: noop,
            removeOption: noop
        };
        return {
            restrict: "E",
            priority: 100,
            compile: function(element, attr) {
                if (isUndefined(attr.value)) {
                    var interpolateFn = $interpolate(element.text(), true);
                    if (!interpolateFn) {
                        attr.$set("value", element.text())
                    }
                }
                return function(scope, element, attr) {
                    var selectCtrlName = "$selectController",
                    parent = element.parent(),
                    selectCtrl = parent.data(selectCtrlName) || parent.parent().data(selectCtrlName);
                    if (selectCtrl && selectCtrl.databound) {
                        element.prop("selected", false)
                    } else {
                        selectCtrl = nullSelectCtrl
                    }
                    if (interpolateFn) {
                        scope.$watch(interpolateFn,
                        function interpolateWatchAction(newVal, oldVal) {
                            attr.$set("value", newVal);
                            if (newVal !== oldVal) selectCtrl.removeOption(oldVal);
                            selectCtrl.addOption(newVal)
                        })
                    } else {
                        selectCtrl.addOption(attr.value)
                    }
                    element.on("$destroy",
                    function() {
                        selectCtrl.removeOption(attr.value)
                    })
                }
            }
        }
    }];
    var styleDirective = valueFn({
        restrict: "E",
        terminal: true
    });
    bindJQuery();
    publishExternalAPI(angular);
    jqLite(document).ready(function() {
        angularInit(document, bootstrap)
    })
})(window, document);
angular.element(document).find("head").prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}</style>'); (function(window, angular, undefined) {
    "use strict";
    angular.module("ngAnimate", ["ng"]).config(["$provide", "$animateProvider",
    function($provide, $animateProvider) {
        var noop = angular.noop;
        var forEach = angular.forEach;
        var selectors = $animateProvider.$$selectors;
        var NG_ANIMATE_STATE = "$$ngAnimateState";
        var NG_ANIMATE_CLASS_NAME = "ng-animate";
        var rootAnimateState = {
            running: true
        };
        $provide.decorator("$animate", ["$delegate", "$injector", "$sniffer", "$rootElement", "$timeout", "$rootScope",
        function($delegate, $injector, $sniffer, $rootElement, $timeout, $rootScope) {
            $rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
            function lookup(name) {
                if (name) {
                    var matches = [],
                    flagMap = {},
                    classes = name.substr(1).split(".");
                    if ($sniffer.transitions || $sniffer.animations) {
                        classes.push("")
                    }
                    for (var i = 0; i < classes.length; i++) {
                        var klass = classes[i],
                        selectorFactoryName = selectors[klass];
                        if (selectorFactoryName && !flagMap[klass]) {
                            matches.push($injector.get(selectorFactoryName));
                            flagMap[klass] = true
                        }
                    }
                    return matches
                }
            }
            return {
                enter: function(element, parent, after, done) {
                    this.enabled(false, element);
                    $delegate.enter(element, parent, after);
                    $rootScope.$$postDigest(function() {
                        performAnimation("enter", "ng-enter", element, parent, after,
                        function() {
                            done && $timeout(done, 0, false)
                        })
                    })
                },
                leave: function(element, done) {
                    cancelChildAnimations(element);
                    this.enabled(false, element);
                    $rootScope.$$postDigest(function() {
                        performAnimation("leave", "ng-leave", element, null, null,
                        function() {
                            $delegate.leave(element, done)
                        })
                    })
                },
                move: function(element, parent, after, done) {
                    cancelChildAnimations(element);
                    this.enabled(false, element);
                    $delegate.move(element, parent, after);
                    $rootScope.$$postDigest(function() {
                        performAnimation("move", "ng-move", element, null, null,
                        function() {
                            done && $timeout(done, 0, false)
                        })
                    })
                },
                addClass: function(element, className, done) {
                    performAnimation("addClass", className, element, null, null,
                    function() {
                        $delegate.addClass(element, className, done)
                    })
                },
                removeClass: function(element, className, done) {
                    performAnimation("removeClass", className, element, null, null,
                    function() {
                        $delegate.removeClass(element, className, done)
                    })
                },
                enabled: function(value, element) {
                    switch (arguments.length) {
                    case 2:
                        if (value) {
                            cleanup(element)
                        } else {
                            var data = element.data(NG_ANIMATE_STATE) || {};
                            data.structural = true;
                            data.running = true;
                            element.data(NG_ANIMATE_STATE, data)
                        }
                        break;
                    case 1:
                        rootAnimateState.running = !value;
                        break;
                    default:
                        value = !rootAnimateState.running;
                        break
                    }
                    return !! value
                }
            };
            function performAnimation(event, className, element, parent, after, onComplete) {
                var classes = (element.attr("class") || "") + " " + className;
                var animationLookup = (" " + classes).replace(/\s+/g, "."),
                animations = [];
                forEach(lookup(animationLookup),
                function(animation, index) {
                    animations.push({
                        start: animation[event]
                    })
                });
                if (!parent) {
                    parent = after ? after.parent() : element.parent()
                }
                var disabledAnimation = {
                    running: true
                };
                if ((parent.inheritedData(NG_ANIMATE_STATE) || disabledAnimation).running || animations.length == 0) {
                    done();
                    return
                }
                var ngAnimateState = element.data(NG_ANIMATE_STATE) || {};
                var isClassBased = event == "addClass" || event == "removeClass";
                if (ngAnimateState.running) {
                    if (isClassBased && ngAnimateState.structural) {
                        onComplete && onComplete();
                        return
                    }
                    $timeout.cancel(ngAnimateState.flagTimer);
                    cancelAnimations(ngAnimateState.animations); (ngAnimateState.done || noop)()
                }
                element.data(NG_ANIMATE_STATE, {
                    running: true,
                    structural: !isClassBased,
                    animations: animations,
                    done: done
                });
                element.addClass(NG_ANIMATE_CLASS_NAME);
                forEach(animations,
                function(animation, index) {
                    var fn = function() {
                        progress(index)
                    };
                    if (animation.start) {
                        animation.endFn = isClassBased ? animation.start(element, className, fn) : animation.start(element, fn)
                    } else {
                        fn()
                    }
                });
                function progress(index) {
                    animations[index].done = true; (animations[index].endFn || noop)();
                    for (var i = 0; i < animations.length; i++) {
                        if (!animations[i].done) return
                    }
                    done()
                }
                function done() {
                    if (!done.hasBeenRun) {
                        done.hasBeenRun = true;
                        var data = element.data(NG_ANIMATE_STATE);
                        if (data) {
                            if (isClassBased) {
                                cleanup(element)
                            } else {
                                data.flagTimer = $timeout(function() {
                                    cleanup(element)
                                },
                                0, false);
                                element.data(NG_ANIMATE_STATE, data)
                            }
                        } (onComplete || noop)()
                    }
                }
            }
            function cancelChildAnimations(element) {
                angular.forEach(element[0].querySelectorAll("." + NG_ANIMATE_CLASS_NAME),
                function(element) {
                    element = angular.element(element);
                    var data = element.data(NG_ANIMATE_STATE);
                    if (data) {
                        cancelAnimations(data.animations);
                        cleanup(element)
                    }
                })
            }
            function cancelAnimations(animations) {
                var isCancelledFlag = true;
                forEach(animations,
                function(animation) { (animation.endFn || noop)(isCancelledFlag)
                })
            }
            function cleanup(element) {
                element.removeClass(NG_ANIMATE_CLASS_NAME);
                element.removeData(NG_ANIMATE_STATE)
            }
        }]);
        $animateProvider.register("", ["$window", "$sniffer", "$timeout",
        function($window, $sniffer, $timeout) {
            var forEach = angular.forEach;
            var transitionProp, transitionendEvent, animationProp, animationendEvent;
            if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
                transitionProp = "WebkitTransition";
                transitionendEvent = "webkitTransitionEnd transitionend"
            } else {
                transitionProp = "transition";
                transitionendEvent = "transitionend"
            }
            if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) {
                animationProp = "WebkitAnimation";
                animationendEvent = "webkitAnimationEnd animationend"
            } else {
                animationProp = "animation";
                animationendEvent = "animationend"
            }
            var durationKey = "Duration",
            propertyKey = "Property",
            delayKey = "Delay",
            animationIterationCountKey = "IterationCount",
            ELEMENT_NODE = 1;
            var NG_ANIMATE_PARENT_KEY = "$ngAnimateKey";
            var lookupCache = {};
            var parentCounter = 0;
            var animationReflowQueue = [],
            animationTimer,
            timeOut = false;
            function afterReflow(callback) {
                animationReflowQueue.push(callback);
                $timeout.cancel(animationTimer);
                animationTimer = $timeout(function() {
                    angular.forEach(animationReflowQueue,
                    function(fn) {
                        fn()
                    });
                    animationReflowQueue = [];
                    animationTimer = null;
                    lookupCache = {}
                },
                10, false)
            }
            function getElementAnimationDetails(element, cacheKey, onlyCheckTransition) {
                var data = lookupCache[cacheKey];
                if (!data) {
                    var transitionDuration = 0,
                    transitionDelay = 0,
                    animationDuration = 0,
                    animationDelay = 0;
                    forEach(element,
                    function(element) {
                        if (element.nodeType == ELEMENT_NODE) {
                            var elementStyles = $window.getComputedStyle(element) || {};
                            transitionDuration = Math.max(parseMaxTime(elementStyles[transitionProp + durationKey]), transitionDuration);
                            if (!onlyCheckTransition) {
                                transitionDelay = Math.max(parseMaxTime(elementStyles[transitionProp + delayKey]), transitionDelay);
                                animationDelay = Math.max(parseMaxTime(elementStyles[animationProp + delayKey]), animationDelay);
                                var aDuration = parseMaxTime(elementStyles[animationProp + durationKey]);
                                if (aDuration > 0) {
                                    aDuration *= parseInt(elementStyles[animationProp + animationIterationCountKey]) || 1
                                }
                                animationDuration = Math.max(aDuration, animationDuration)
                            }
                        }
                    });
                    data = {
                        transitionDelay: transitionDelay,
                        animationDelay: animationDelay,
                        transitionDuration: transitionDuration,
                        animationDuration: animationDuration
                    };
                    lookupCache[cacheKey] = data
                }
                return data
            }
            function parseMaxTime(str) {
                var total = 0,
                values = angular.isString(str) ? str.split(/\s*,\s*/) : [];
                forEach(values,
                function(value) {
                    total = Math.max(parseFloat(value) || 0, total)
                });
                return total
            }
            function getCacheKey(element) {
                var parent = element.parent();
                var parentID = parent.data(NG_ANIMATE_PARENT_KEY);
                if (!parentID) {
                    parent.data(NG_ANIMATE_PARENT_KEY, ++parentCounter);
                    parentID = parentCounter
                }
                return parentID + "-" + element[0].className
            }
            function animate(element, className, done) {
                var cacheKey = getCacheKey(element);
                if (getElementAnimationDetails(element, cacheKey, true).transitionDuration > 0) {
                    done();
                    return
                }
                element.addClass(className);
                var timings = getElementAnimationDetails(element, cacheKey + " " + className);
                var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration);
                if (maxDuration > 0) {
                    var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * 1e3,
                    startTime = Date.now(),
                    node = element[0];
                    if (timings.transitionDuration > 0) {
                        node.style[transitionProp + propertyKey] = "none"
                    }
                    var activeClassName = "";
                    forEach(className.split(" "),
                    function(klass, i) {
                        activeClassName += (i > 0 ? " ": "") + klass + "-active"
                    });
                    var css3AnimationEvents = animationendEvent + " " + transitionendEvent;
                    afterReflow(function() {
                        if (timings.transitionDuration > 0) {
                            node.style[transitionProp + propertyKey] = ""
                        }
                        element.addClass(activeClassName)
                    });
                    element.on(css3AnimationEvents, onAnimationProgress);
                    return function onEnd(cancelled) {
                        element.off(css3AnimationEvents, onAnimationProgress);
                        element.removeClass(className);
                        element.removeClass(activeClassName);
                        if (cancelled) {
                            done()
                        }
                    }
                } else {
                    element.removeClass(className);
                    done()
                }
                function onAnimationProgress(event) {
                    event.stopPropagation();
                    var ev = event.originalEvent || event;
                    var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now();
                    if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && ev.elapsedTime >= maxDuration) {
                        done()
                    }
                }
            }
            return {
                enter: function(element, done) {
                    return animate(element, "ng-enter", done)
                },
                leave: function(element, done) {
                    return animate(element, "ng-leave", done)
                },
                move: function(element, done) {
                    return animate(element, "ng-move", done)
                },
                addClass: function(element, className, done) {
                    return animate(element, suffixClasses(className, "-add"), done)
                },
                removeClass: function(element, className, done) {
                    return animate(element, suffixClasses(className, "-remove"), done)
                }
            };
            function suffixClasses(classes, suffix) {
                var className = "";
                classes = angular.isArray(classes) ? classes: classes.split(/\s+/);
                forEach(classes,
                function(klass, i) {
                    if (klass && klass.length > 0) {
                        className += (i > 0 ? " ": "") + klass + suffix
                    }
                });
                return className
            }
        }])
    }])
})(window, window.angular);
$(window).on("keyup",
function(e) {
    if (e.which === 9) {
        var focus = document.activeElement,
        dropdown = $(".custom.dropdown");
        dropdown.each(function() {
            if (focus === $(this).find("a.current")[0]) {
                $(this).find(".selector").focus().click();
                e.stopPropagation()
            }
        })
    }
});
var libFuncName = null;
if (typeof jQuery === "undefined" && typeof Zepto === "undefined" && typeof $ === "function") {
    libFuncName = $
} else if (typeof jQuery === "function") {
    libFuncName = jQuery
} else if (typeof Zepto === "function") {
    libFuncName = Zepto
} else {
    throw new TypeError
} (function($, window, document, undefined) {
    "use strict";
    $("head").append('<meta class="foundation-mq-small">');
    $("head").append('<meta class="foundation-mq-medium">');
    $("head").append('<meta class="foundation-mq-large">');
    window.matchMedia = window.matchMedia ||
    function(doc, undefined) {
        "use strict";
        var bool, docElem = doc.documentElement,
        refNode = docElem.firstElementChild || docElem.firstChild,
        fakeBody = doc.createElement("body"),
        div = doc.createElement("div");
        div.id = "mq-test-1";
        div.style.cssText = "position:absolute;top:-100em";
        fakeBody.style.background = "none";
        fakeBody.appendChild(div);
        return function(q) {
            div.innerHTML = '&shy;<style media="' + q + '"> #mq-test-1 { width: 42px; }</style>';
            docElem.insertBefore(fakeBody, refNode);
            bool = div.offsetWidth === 42;
            docElem.removeChild(fakeBody);
            return {
                matches: bool,
                media: q
            }
        }
    } (document);
    if (!Array.prototype.filter) {
        Array.prototype.filter = function(fun) {
            "use strict";
            if (this == null) {
                throw new TypeError
            }
            var t = Object(this),
            len = t.length >>> 0;
            if (typeof fun !== "function") {
                return
            }
            var res = [],
            thisp = arguments[1];
            for (var i = 0; i < len; i++) {
                if (i in t) {
                    var val = t[i];
                    if (fun && fun.call(thisp, val, i, t)) {
                        res.push(val)
                    }
                }
            }
            return res
        }
    }
    if (!Function.prototype.bind) {
        Function.prototype.bind = function(oThis) {
            if (typeof this !== "function") {
                throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable")
            }
            var aArgs = Array.prototype.slice.call(arguments, 1),
            fToBind = this,
            fNOP = function() {},
            fBound = function() {
                return fToBind.apply(this instanceof fNOP && oThis ? this: oThis, aArgs.concat(Array.prototype.slice.call(arguments)))
            };
            fNOP.prototype = this.prototype;
            fBound.prototype = new fNOP;
            return fBound
        }
    }
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(searchElement) {
            "use strict";
            if (this == null) {
                throw new TypeError
            }
            var t = Object(this);
            var len = t.length >>> 0;
            if (len === 0) {
                return - 1
            }
            var n = 0;
            if (arguments.length > 1) {
                n = Number(arguments[1]);
                if (n != n) {
                    n = 0
                } else if (n != 0 && n != Infinity && n != -Infinity) {
                    n = (n > 0 || -1) * Math.floor(Math.abs(n))
                }
            }
            if (n >= len) {
                return - 1
            }
            var k = n >= 0 ? n: Math.max(len - Math.abs(n), 0);
            for (; k < len; k++) {
                if (k in t && t[k] === searchElement) {
                    return k
                }
            }
            return - 1
        }
    }
    $.fn.stop = $.fn.stop ||
    function() {
        return this
    };
    window.Foundation = {
        name: "Foundation",
        version: "4.3.2",
        cache: {},
        media_queries: {
            small: $(".foundation-mq-small").css("font-family").replace(/\'/g, ""),
            medium: $(".foundation-mq-medium").css("font-family").replace(/\'/g, ""),
            large: $(".foundation-mq-large").css("font-family").replace(/\'/g, "")
        },
        stylesheet: $("<style></style>").appendTo("head")[0].sheet,
        init: function(scope, libraries, method, options, response, nc) {
            var library_arr, args = [scope, method, options, response],
            responses = [],
            nc = nc || false;
            if (nc) this.nc = nc;
            this.rtl = /rtl/i.test($("html").attr("dir"));
            this.scope = scope || this.scope;
            if (libraries && typeof libraries === "string" && !/reflow/i.test(libraries)) {
                if (/off/i.test(libraries)) return this.off();
                library_arr = libraries.split(" ");
                if (library_arr.length > 0) {
                    for (var i = library_arr.length - 1; i >= 0; i--) {
                        responses.push(this.init_lib(library_arr[i], args))
                    }
                }
            } else {
                if (/reflow/i.test(libraries)) args[1] = "reflow";
                for (var lib in this.libs) {
                    responses.push(this.init_lib(lib, args))
                }
            }
            if (typeof libraries === "function") {
                args.unshift(libraries)
            }
            return this.response_obj(responses, args)
        },
        response_obj: function(response_arr, args) {
            for (var i = 0,
            len = args.length; i < len; i++) {
                if (typeof args[i] === "function") {
                    return args[i]({
                        errors: response_arr.filter(function(s) {
                            if (typeof s === "string") return s
                        })
                    })
                }
            }
            return response_arr
        },
        init_lib: function(lib, args) {
            return this.trap(function() {
                if (this.libs.hasOwnProperty(lib)) {
                    this.patch(this.libs[lib]);
                    return this.libs[lib].init.apply(this.libs[lib], args)
                } else {
                    return function() {}
                }
            }.bind(this), lib)
        },
        trap: function(fun, lib) {
            if (!this.nc) {
                try {
                    return fun()
                } catch(e) {
                    return this.error({
                        name: lib,
                        message: "could not be initialized",
                        more: e.name + " " + e.message
                    })
                }
            }
            return fun()
        },
        patch: function(lib) {
            this.fix_outer(lib);
            lib.scope = this.scope;
            lib.rtl = this.rtl
        },
        inherit: function(scope, methods) {
            var methods_arr = methods.split(" ");
            for (var i = methods_arr.length - 1; i >= 0; i--) {
                if (this.lib_methods.hasOwnProperty(methods_arr[i])) {
                    this.libs[scope.name][methods_arr[i]] = this.lib_methods[methods_arr[i]]
                }
            }
        },
        random_str: function(length) {
            var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
            if (!length) {
                length = Math.floor(Math.random() * chars.length)
            }
            var str = "";
            for (var i = 0; i < length; i++) {
                str += chars[Math.floor(Math.random() * chars.length)]
            }
            return str
        },
        libs: {},
        lib_methods: {
            set_data: function(node, data) {
                var id = [this.name, +new Date, Foundation.random_str(5)].join("-");
                Foundation.cache[id] = data;
                node.attr("data-" + this.name + "-id", id);
                return data
            },
            get_data: function(node) {
                return Foundation.cache[node.attr("data-" + this.name + "-id")]
            },
            remove_data: function(node) {
                if (node) {
                    delete Foundation.cache[node.attr("data-" + this.name + "-id")];
                    node.attr("data-" + this.name + "-id", "")
                } else {
                    $("[data-" + this.name + "-id]").each(function() {
                        delete Foundation.cache[$(this).attr("data-" + this.name + "-id")];
                        $(this).attr("data-" + this.name + "-id", "")
                    })
                }
            },
            throttle: function(fun, delay) {
                var timer = null;
                return function() {
                    var context = this,
                    args = arguments;
                    clearTimeout(timer);
                    timer = setTimeout(function() {
                        fun.apply(context, args)
                    },
                    delay)
                }
            },
            data_options: function(el) {
                var opts = {},
                ii, p, opts_arr = (el.attr("data-options") || ":").split(";"),
                opts_len = opts_arr.length;
                function isNumber(o) {
                    return ! isNaN(o - 0) && o !== null && o !== "" && o !== false && o !== true
                }
                function trim(str) {
                    if (typeof str === "string") return $.trim(str);
                    return str
                }
                for (ii = opts_len - 1; ii >= 0; ii--) {
                    p = opts_arr[ii].split(":");
                    if (/true/i.test(p[1])) p[1] = true;
                    if (/false/i.test(p[1])) p[1] = false;
                    if (isNumber(p[1])) p[1] = parseInt(p[1], 10);
                    if (p.length === 2 && p[0].length > 0) {
                        opts[trim(p[0])] = trim(p[1])
                    }
                }
                return opts
            },
            delay: function(fun, delay) {
                return setTimeout(fun, delay)
            },
            scrollTo: function(el, to, duration) {
                if (duration < 0) return;
                var difference = to - $(window).scrollTop();
                var perTick = difference / duration * 10;
                this.scrollToTimerCache = setTimeout(function() {
                    if (!isNaN(parseInt(perTick, 10))) {
                        window.scrollTo(0, $(window).scrollTop() + perTick);
                        this.scrollTo(el, to, duration - 10)
                    }
                }.bind(this), 10)
            },
            scrollLeft: function(el) {
                if (!el.length) return;
                return "scrollLeft" in el[0] ? el[0].scrollLeft: el[0].pageXOffset
            },
            empty: function(obj) {
                if (obj.length && obj.length > 0) return false;
                if (obj.length && obj.length === 0) return true;
                for (var key in obj) {
                    if (hasOwnProperty.call(obj, key)) return false
                }
                return true
            },
            addCustomRule: function(rule, media) {
                if (media === undefined) {
                    Foundation.stylesheet.insertRule(rule, Foundation.stylesheet.cssRules.length)
                } else {
                    var query = Foundation.media_queries[media];
                    if (query !== undefined) {
                        Foundation.stylesheet.insertRule("@media " + Foundation.media_queries[media] + "{ " + rule + " }")
                    }
                }
            }
        },
        fix_outer: function(lib) {
            lib.outerHeight = function(el, bool) {
                if (typeof Zepto === "function") {
                    return el.height()
                }
                if (typeof bool !== "undefined") {
                    return el.outerHeight(bool)
                }
                return el.outerHeight()
            };
            lib.outerWidth = function(el, bool) {
                if (typeof Zepto === "function") {
                    return el.width()
                }
                if (typeof bool !== "undefined") {
                    return el.outerWidth(bool)
                }
                return el.outerWidth()
            }
        },
        error: function(error) {
            return error.name + " " + error.message + "; " + error.more
        },
        off: function() {
            $(this.scope).off(".fndtn");
            $(window).off(".fndtn");
            return true
        },
        zj: $
    };
    $.fn.foundation = function() {
        var args = Array.prototype.slice.call(arguments, 0);
        return this.each(function() {
            Foundation.init.apply(Foundation, [this].concat(args));
            return this
        })
    }
})(libFuncName, this, this.document); (function($, window, document, undefined) {
    "use strict";
    Foundation.libs.reveal = {
        name: "reveal",
        version: "4.3.2",
        locked: false,
        settings: {
            animation: "fadeAndPop",
            animationSpeed: 250,
            closeOnBackgroundClick: true,
            closeOnEsc: true,
            dismissModalClass: "close-reveal-modal",
            bgClass: "reveal-modal-bg",
            open: function() {},
            opened: function() {},
            close: function() {},
            closed: function() {},
            bg: $(".reveal-modal-bg"),
            css: {
                open: {
                    opacity: 0,
                    visibility: "visible",
                    display: "block"
                },
                close: {
                    opacity: 1,
                    visibility: "hidden",
                    display: "none"
                }
            }
        },
        init: function(scope, method, options) {
            Foundation.inherit(this, "data_options delay");
            if (typeof method === "object") {
                $.extend(true, this.settings, method)
            } else if (typeof options !== "undefined") {
                $.extend(true, this.settings, options)
            }
            if (typeof method !== "string") {
                this.events();
                return this.settings.init
            } else {
                return this[method].call(this, options)
            }
        },
        events: function() {
            var self = this;
            $(this.scope).off(".fndtn.reveal").on("click.fndtn.reveal", "[data-reveal-id]",
            function(e) {
                e.preventDefault();
                if (!self.locked) {
                    var element = $(this),
                    ajax = element.data("reveal-ajax");
                    self.locked = true;
                    if (typeof ajax === "undefined") {
                        self.open.call(self, element)
                    } else {
                        var url = ajax === true ? element.attr("href") : ajax;
                        self.open.call(self, element, {
                            url: url
                        })
                    }
                }
            }).on("click.fndtn.reveal touchend", this.close_targets(),
            function(e) {
                e.preventDefault();
                if (!self.locked) {
                    var settings = $.extend({},
                    self.settings, self.data_options($(".reveal-modal.open"))),
                    bgClicked = $(e.target)[0] === $("." + settings.bgClass)[0];
                    if (bgClicked && !settings.closeOnBackgroundClick) {
                        return
                    }
                    self.locked = true;
                    self.close.call(self, bgClicked ? $(".reveal-modal.open") : $(this).closest(".reveal-modal"))
                }
            });
            if ($(this.scope).hasClass("reveal-modal")) {
                $(this.scope).on("open.fndtn.reveal", this.settings.open).on("opened.fndtn.reveal", this.settings.opened).on("opened.fndtn.reveal", this.open_video).on("close.fndtn.reveal", this.settings.close).on("closed.fndtn.reveal", this.settings.closed).on("closed.fndtn.reveal", this.close_video)
            } else {
                $(this.scope).on("open.fndtn.reveal", ".reveal-modal", this.settings.open).on("opened.fndtn.reveal", ".reveal-modal", this.settings.opened).on("opened.fndtn.reveal", ".reveal-modal", this.open_video).on("close.fndtn.reveal", ".reveal-modal", this.settings.close).on("closed.fndtn.reveal", ".reveal-modal", this.settings.closed).on("closed.fndtn.reveal", ".reveal-modal", this.close_video)
            }
            $("body").bind("keyup.reveal",
            function(event) {
                var open_modal = $(".reveal-modal.open"),
                settings = $.extend({},
                self.settings, self.data_options(open_modal));
                if (event.which === 27 && settings.closeOnEsc) {
                    open_modal.foundation("reveal", "close")
                }
            });
            return true
        },
        open: function(target, ajax_settings) {
            if (target) {
                if (typeof target.selector !== "undefined") {
                    var modal = $("#" + target.data("reveal-id"))
                } else {
                    var modal = $(this.scope);
                    ajax_settings = target
                }
            } else {
                var modal = $(this.scope)
            }
            if (!modal.hasClass("open")) {
                var open_modal = $(".reveal-modal.open");
                if (typeof modal.data("css-top") === "undefined") {
                    modal.data("css-top", parseInt(modal.css("top"), 10)).data("offset", this.cache_offset(modal))
                }
                modal.trigger("open");
                if (open_modal.length < 1) {
                    this.toggle_bg()
                }
                if (typeof ajax_settings === "undefined" || !ajax_settings.url) {
                    this.hide(open_modal, this.settings.css.close);
                    this.show(modal, this.settings.css.open)
                } else {
                    var self = this,
                    old_success = typeof ajax_settings.success !== "undefined" ? ajax_settings.success: null;
                    $.extend(ajax_settings, {
                        success: function(data, textStatus, jqXHR) {
                            if ($.isFunction(old_success)) {
                                old_success(data, textStatus, jqXHR)
                            }
                            modal.html(data);
                            $(modal).foundation("section", "reflow");
                            self.hide(open_modal, self.settings.css.close);
                            self.show(modal, self.settings.css.open)
                        }
                    });
                    $.ajax(ajax_settings)
                }
            }
        },
        close: function(modal) {
            var modal = modal && modal.length ? modal: $(this.scope),
            open_modals = $(".reveal-modal.open");
            if (open_modals.length > 0) {
                this.locked = true;
                modal.trigger("close");
                this.toggle_bg();
                this.hide(open_modals, this.settings.css.close)
            }
        },
        close_targets: function() {
            var base = "." + this.settings.dismissModalClass;
            if (this.settings.closeOnBackgroundClick) {
                return base + ", ." + this.settings.bgClass
            }
            return base
        },
        toggle_bg: function() {
            if ($("." + this.settings.bgClass).length === 0) {
                this.settings.bg = $("<div />", {
                    "class": this.settings.bgClass
                }).appendTo("body")
            }
            if (this.settings.bg.filter(":visible").length > 0) {
                this.hide(this.settings.bg)
            } else {
                this.show(this.settings.bg)
            }
        },
        show: function(el, css) {
            if (css) {
                if (el.parent("body").length === 0) {
                    var placeholder = el.wrap('<div style="display: none;" />').parent();
                    el.on("closed.fndtn.reveal.wrapped",
                    function() {
                        el.detach().appendTo(placeholder);
                        el.unwrap().unbind("closed.fndtn.reveal.wrapped")
                    });
                    el.detach().appendTo("body")
                }
                if (/pop/i.test(this.settings.animation)) {
                    css.top = $(window).scrollTop() - el.data("offset") + "px";
                    var end_css = {
                        top: $(window).scrollTop() + el.data("css-top") + "px",
                        opacity: 1
                    };
                    return this.delay(function() {
                        return el.css(css).animate(end_css, this.settings.animationSpeed, "linear",
                        function() {
                            this.locked = false;
                            el.trigger("opened")
                        }.bind(this)).addClass("open")
                    }.bind(this), this.settings.animationSpeed / 2)
                }
                if (/fade/i.test(this.settings.animation)) {
                    var end_css = {
                        opacity: 1
                    };
                    return this.delay(function() {
                        return el.css(css).animate(end_css, this.settings.animationSpeed, "linear",
                        function() {
                            this.locked = false;
                            el.trigger("opened")
                        }.bind(this)).addClass("open")
                    }.bind(this), this.settings.animationSpeed / 2)
                }
                return el.css(css).show().css({
                    opacity: 1
                }).addClass("open").trigger("opened")
            }
            if (/fade/i.test(this.settings.animation)) {
                return el.fadeIn(this.settings.animationSpeed / 2)
            }
            return el.show()
        },
        hide: function(el, css) {
            if (css) {
                if (/pop/i.test(this.settings.animation)) {
                    var end_css = {
                        top: -$(window).scrollTop() - el.data("offset") + "px",
                        opacity: 0
                    };
                    return this.delay(function() {
                        return el.animate(end_css, this.settings.animationSpeed, "linear",
                        function() {
                            this.locked = false;
                            el.css(css).trigger("closed")
                        }.bind(this)).removeClass("open")
                    }.bind(this), this.settings.animationSpeed / 2)
                }
                if (/fade/i.test(this.settings.animation)) {
                    var end_css = {
                        opacity: 0
                    };
                    return this.delay(function() {
                        return el.animate(end_css, this.settings.animationSpeed, "linear",
                        function() {
                            this.locked = false;
                            el.css(css).trigger("closed")
                        }.bind(this)).removeClass("open")
                    }.bind(this), this.settings.animationSpeed / 2)
                }
                return el.hide().css(css).removeClass("open").trigger("closed")
            }
            if (/fade/i.test(this.settings.animation)) {
                return el.fadeOut(this.settings.animationSpeed / 2)
            }
            return el.hide()
        },
        close_video: function(e) {
            var video = $(this).find(".flex-video"),
            iframe = video.find("iframe");
            if (iframe.length > 0) {
                iframe.attr("data-src", iframe[0].src);
                iframe.attr("src", "about:blank");
                video.hide()
            }
        },
        open_video: function(e) {
            var video = $(this).find(".flex-video"),
            iframe = video.find("iframe");
            if (iframe.length > 0) {
                var data_src = iframe.attr("data-src");
                if (typeof data_src === "string") {
                    iframe[0].src = iframe.attr("data-src")
                } else {
                    var src = iframe[0].src;
                    iframe[0].src = undefined;
                    iframe[0].src = src
                }
                video.show()
            }
        },
        cache_offset: function(modal) {
            var offset = modal.show().height() + parseInt(modal.css("top"), 10);
            modal.hide();
            return offset
        },
        off: function() {
            $(this.scope).off(".fndtn.reveal")
        },
        reflow: function() {}
    }
})(Foundation.zj, this, this.document); (function($, window, document, undefined) {
    "use strict";
    Foundation.libs.forms = {
        name: "forms",
        version: "4.3.2",
        cache: {},
        settings: {
            disable_class: "no-custom",
            last_combo: null
        },
        init: function(scope, method, options) {
            if (typeof method === "object") {
                $.extend(true, this.settings, method)
            }
            if (typeof method !== "string") {
                if (!this.settings.init) {
                    this.events()
                }
                this.assemble();
                return this.settings.init
            } else {
                return this[method].call(this, options)
            }
        },
        assemble: function() {
            var forms = this;
            $('form.custom input[type="radio"],[type="checkbox"]', $(this.scope)).not('[data-customforms="disabled"]').not("." + this.settings.disable_class).each(function(idx, sel) {
                forms.set_custom_markup(sel)
            }).change(function() {
                forms.set_custom_markup(this)
            });
            $("form.custom select", $(this.scope)).not('[data-customforms="disabled"]').not("." + this.settings.disable_class).not("[multiple=multiple]").each(this.append_custom_select)
        },
        events: function() {
            var self = this;
            $(this.scope).on("click.fndtn.forms", "form.custom span.custom.checkbox",
            function(e) {
                e.preventDefault();
                e.stopPropagation();
                self.toggle_checkbox($(this))
            }).on("click.fndtn.forms", "form.custom span.custom.radio",
            function(e) {
                e.preventDefault();
                e.stopPropagation();
                self.toggle_radio($(this))
            }).on("change.fndtn.forms", "form.custom select",
            function(e, force_refresh) {
                if ($(this).is('[data-customforms="disabled"]')) return;
                self.refresh_custom_select($(this), force_refresh)
            }).on("click.fndtn.forms", "form.custom label",
            function(e) {
                if ($(e.target).is("label")) {
                    var $associatedElement = $("#" + self.escape($(this).attr("for"))).not('[data-customforms="disabled"]'),
                    $customCheckbox,
                    $customRadio;
                    if ($associatedElement.length !== 0) {
                        if ($associatedElement.attr("type") === "checkbox") {
                            e.preventDefault();
                            $customCheckbox = $(this).find("span.custom.checkbox");
                            if ($customCheckbox.length === 0) {
                                $customCheckbox = $associatedElement.add(this).siblings("span.custom.checkbox").first()
                            }
                            self.toggle_checkbox($customCheckbox)
                        } else if ($associatedElement.attr("type") === "radio") {
                            e.preventDefault();
                            $customRadio = $(this).find("span.custom.radio");
                            if ($customRadio.length === 0) {
                                $customRadio = $associatedElement.add(this).siblings("span.custom.radio").first()
                            }
                            self.toggle_radio($customRadio)
                        }
                    }
                }
            }).on("mousedown.fndtn.forms", "form.custom div.custom.dropdown",
            function() {
                return false
            }).on("click.fndtn.forms", "form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector",
            function(e) {
                var $this = $(this),
                $dropdown = $this.closest("div.custom.dropdown"),
                $select = getFirstPrevSibling($dropdown, "select");
                if (!$dropdown.hasClass("open")) $(self.scope).trigger("click");
                e.preventDefault();
                if (false === $select.is(":disabled")) {
                    $dropdown.toggleClass("open");
                    if ($dropdown.hasClass("open")) {
                        $(self.scope).on("click.fndtn.forms.customdropdown",
                        function() {
                            $dropdown.removeClass("open");
                            $(self.scope).off(".fndtn.forms.customdropdown")
                        })
                    } else {
                        $(self.scope).on(".fndtn.forms.customdropdown")
                    }
                    return false
                }
            }).on("click.fndtn.forms touchend.fndtn.forms", "form.custom div.custom.dropdown li",
            function(e) {
                var $this = $(this),
                $customDropdown = $this.closest("div.custom.dropdown"),
                $select = getFirstPrevSibling($customDropdown, "select"),
                selectedIndex = 0;
                e.preventDefault();
                e.stopPropagation();
                if (!$(this).hasClass("disabled")) {
                    $("div.dropdown").not($customDropdown).removeClass("open");
                    var $oldThis = $this.closest("ul").find("li.selected");
                    $oldThis.removeClass("selected");
                    $this.addClass("selected");
                    $customDropdown.removeClass("open").find("a.current").text($this.text());
                    $this.closest("ul").find("li").each(function(index) {
                        if ($this[0] === this) {
                            selectedIndex = index
                        }
                    });
                    $select[0].selectedIndex = selectedIndex;
                    $select.data("prevalue", $oldThis.html());
                    if (typeof document.createEvent != "undefined") {
                        var event = document.createEvent("HTMLEvents");
                        event.initEvent("change", true, true);
                        $select[0].dispatchEvent(event)
                    } else {
                        $select[0].fireEvent("onchange")
                    }
                }
            });
            $(window).on("keydown",
            function(e) {
                var focus = document.activeElement,
                self = Foundation.libs.forms,
                dropdown = $(".custom.dropdown"),
                select = getFirstPrevSibling(dropdown, "select"),
                inputs = $("input,select,textarea,button");
                if (dropdown.length > 0 && dropdown.hasClass("open")) {
                    e.preventDefault();
                    if (e.which === 9) {
                        $(inputs[$(inputs).index(select) + 1]).focus();
                        dropdown.removeClass("open")
                    }
                    if (e.which === 13) {
                        dropdown.find("li.selected").trigger("click")
                    }
                    if (e.which === 27) {
                        dropdown.removeClass("open")
                    }
                    if (e.which >= 65 && e.which <= 90) {
                        var next = self.go_to(dropdown, e.which),
                        current = dropdown.find("li.selected");
                        if (next) {
                            current.removeClass("selected");
                            self.scrollTo(next.addClass("selected"), 300)
                        }
                    }
                    if (e.which === 38) {
                        var current = dropdown.find("li.selected"),
                        prev = current.prev(":not(.disabled)");
                        if (prev.length > 0) {
                            prev.parent()[0].scrollTop = prev.parent().scrollTop() - self.outerHeight(prev);
                            current.removeClass("selected");
                            prev.addClass("selected")
                        }
                    } else if (e.which === 40) {
                        var current = dropdown.find("li.selected"),
                        next = current.next(":not(.disabled)");
                        if (next.length > 0) {
                            next.parent()[0].scrollTop = next.parent().scrollTop() + self.outerHeight(next);
                            current.removeClass("selected");
                            next.addClass("selected")
                        }
                    }
                }
            });
            $(window).on("keyup",
            function(e) {
                var focus = document.activeElement,
                dropdown = $(".custom.dropdown");
                if (focus === dropdown.find(".current")[0]) {
                    dropdown.find(".selector").focus().click()
                }
            });
            this.settings.init = true
        },
        go_to: function(dropdown, character) {
            var lis = dropdown.find("li"),
            count = lis.length;
            if (count > 0) {
                for (var i = 0; i < count; i++) {
                    var first_letter = lis.eq(i).text().charAt(0).toLowerCase();
                    if (first_letter === String.fromCharCode(character).toLowerCase()) return lis.eq(i)
                }
            }
        },
        scrollTo: function(el, duration) {
            if (duration < 0) return;
            var parent = el.parent();
            var li_height = this.outerHeight(el);
            var difference = li_height * el.index() - parent.scrollTop();
            var perTick = difference / duration * 10;
            this.scrollToTimerCache = setTimeout(function() {
                if (!isNaN(parseInt(perTick, 10))) {
                    parent[0].scrollTop = parent.scrollTop() + perTick;
                    this.scrollTo(el, duration - 10)
                }
            }.bind(this), 10)
        },
        set_custom_markup: function(sel) {
            var $this = $(sel),
            type = $this.attr("type"),
            $span = $this.next("span.custom." + type);
            if (!$this.parent().hasClass("switch")) {
                $this.addClass("hidden-field")
            }
            if ($span.length === 0) {
                $span = $('<span class="custom ' + type + '"></span>').insertAfter($this)
            }
            $span.toggleClass("checked", $this.is(":checked"));
            $span.toggleClass("disabled", $this.is(":disabled"))
        },
        append_custom_select: function(idx, sel) {
            var self = Foundation.libs.forms,
            $this = $(sel),
            $customSelect = $this.next("div.custom.dropdown"),
            $customList = $customSelect.find("ul"),
            $selectCurrent = $customSelect.find(".current"),
            $selector = $customSelect.find(".selector"),
            $options = $this.find("option"),
            $selectedOption = $options.filter(":selected"),
            copyClasses = $this.attr("class") ? $this.attr("class").split(" ") : [],
            maxWidth = 0,
            liHtml = "",
            $listItems,
            $currentSelect = false;
            if ($customSelect.length === 0) {
                var customSelectSize = $this.hasClass("small") ? "small": $this.hasClass("medium") ? "medium": $this.hasClass("large") ? "large": $this.hasClass("expand") ? "expand": "";
                $customSelect = $('<div class="' + ["custom", "dropdown", customSelectSize].concat(copyClasses).filter(function(item, idx, arr) {
                    if (item === "") return false;
                    return arr.indexOf(item) === idx
                }).join(" ") + '"><a href="#" class="selector"></a><ul /></div>');
                $selector = $customSelect.find(".selector");
                $customList = $customSelect.find("ul");
                liHtml = $options.map(function() {
                    var copyClasses = $(this).attr("class") ? $(this).attr("class") : "";
                    return "<li class='" + copyClasses + "'>" + $(this).html() + "</li>"
                }).get().join("");
                $customList.append(liHtml);
                $currentSelect = $customSelect.prepend('<a href="#" class="current">' + ($selectedOption.html() || "") + "</a>").find(".current");
                $this.after($customSelect).addClass("hidden-field")
            } else {
                liHtml = $options.map(function() {
                    return "<li>" + $(this).html() + "</li>"
                }).get().join("");
                $customList.html("").append(liHtml)
            }
            self.assign_id($this, $customSelect);
            $customSelect.toggleClass("disabled", $this.is(":disabled"));
            $listItems = $customList.find("li");
            self.cache[$customSelect.data("id")] = $listItems.length;
            $options.each(function(index) {
                if (this.selected) {
                    $listItems.eq(index).addClass("selected");
                    if ($currentSelect) {
                        $currentSelect.html($(this).html())
                    }
                }
                if ($(this).is(":disabled")) {
                    $listItems.eq(index).addClass("disabled")
                }
            });
            if (!$customSelect.is(".small, .medium, .large, .expand")) {
                $customSelect.addClass("open");
                var self = Foundation.libs.forms;
                self.hidden_fix.adjust($customList);
                maxWidth = self.outerWidth($listItems) > maxWidth ? self.outerWidth($listItems) : maxWidth;
                Foundation.libs.forms.hidden_fix.reset();
                $customSelect.removeClass("open")
            }
        },
        assign_id: function($select, $customSelect) {
            var id = [ + new Date, Foundation.random_str(5)].join("-");
            $select.attr("data-id", id);
            $customSelect.attr("data-id", id)
        },
        refresh_custom_select: function($select, force_refresh) {
            var self = this;
            var maxWidth = 0,
            $customSelect = $select.next(),
            $options = $select.find("option"),
            $customList = $customSelect.find("ul"),
            $listItems = $customSelect.find("li");
            if ($options.length !== this.cache[$customSelect.data("id")] || force_refresh) {
                $customList.html("");
                var customSelectHtml = "";
                $options.each(function() {
                    var $this = $(this),
                    thisHtml = $this.html(),
                    thisSelected = this.selected;
                    customSelectHtml += '<li class="' + (thisSelected ? " selected ": "") + ($this.is(":disabled") ? " disabled ": "") + '">' + thisHtml + "</li>";
                    if (thisSelected) {
                        $customSelect.find(".current").html(thisHtml)
                    }
                });
                $customList.html(customSelectHtml);
                $customSelect.removeAttr("style");
                $customList.removeAttr("style");
                $customSelect.find("li").each(function() {
                    $customSelect.addClass("open");
                    if (self.outerWidth($(this)) > maxWidth) {
                        maxWidth = self.outerWidth($(this))
                    }
                    $customSelect.removeClass("open")
                });
                $listItems = $customSelect.find("li");
                this.cache[$customSelect.data("id")] = $listItems.length
            }
        },
        refresh_custom_selection: function($select) {
            var selectedValue = $("option:selected", $select).text();
            $("a.current", $select.next()).text(selectedValue)
        },
        toggle_checkbox: function($element) {
            var $input = $element.prev(),
            input = $input[0];
            if (false === $input.is(":disabled")) {
                input.checked = input.checked ? false: true;
                $element.toggleClass("checked");
                $input.trigger("change")
            }
        },
        toggle_radio: function($element) {
            var $input = $element.prev(),
            $form = $input.closest("form.custom"),
            input = $input[0];
            if (false === $input.is(":disabled")) {
                $form.find('input[type="radio"][name="' + this.escape($input.attr("name")) + '"]').next().not($element).removeClass("checked");
                if (!$element.hasClass("checked")) {
                    $element.toggleClass("checked")
                }
                input.checked = $element.hasClass("checked");
                $input.trigger("change")
            }
        },
        escape: function(text) {
            if (!text) return "";
            return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
        },
        hidden_fix: {
            tmp: [],
            hidden: null,
            adjust: function($child) {
                var _self = this;
                _self.hidden = $child.parents();
                _self.hidden = _self.hidden.add($child).filter(":hidden");
                _self.hidden.each(function() {
                    var $elem = $(this);
                    _self.tmp.push($elem.attr("style"));
                    $elem.css({
                        visibility: "hidden",
                        display: "block"
                    })
                })
            },
            reset: function() {
                var _self = this;
                _self.hidden.each(function(i) {
                    var $elem = $(this),
                    _tmp = _self.tmp[i];
                    if (_tmp === undefined) $elem.removeAttr("style");
                    else $elem.attr("style", _tmp)
                });
                _self.tmp = [];
                _self.hidden = null
            }
        },
        off: function() {
            $(this.scope).off(".fndtn.forms")
        },
        reflow: function() {}
    };
    var getFirstPrevSibling = function($el, selector) {
        var $el = $el.prev();
        while ($el.length) {
            if ($el.is(selector)) return $el;
            $el = $el.prev()
        }
        return $()
    }
})(Foundation.zj, this, this.document); (function($, window, document, undefined) {
    "use strict";
    Foundation.libs.topbar = {
        name: "topbar",
        version: "4.3.2",
        settings: {
            index: 0,
            stickyClass: "sticky",
            custom_back_text: true,
            back_text: "Back",
            is_hover: true,
            mobile_show_parent_link: false,
            scrolltop: true,
            init: false
        },
        init: function(section, method, options) {
            Foundation.inherit(this, "data_options addCustomRule");
            var self = this;
            if (typeof method === "object") {
                $.extend(true, this.settings, method)
            } else if (typeof options !== "undefined") {
                $.extend(true, this.settings, options)
            }
            if (typeof method !== "string") {
                $(".top-bar, [data-topbar]").each(function() {
                    $.extend(true, self.settings, self.data_options($(this)));
                    self.settings.$w = $(window);
                    self.settings.$topbar = $(this);
                    self.settings.$section = self.settings.$topbar.find("section");
                    self.settings.$titlebar = self.settings.$topbar.children("ul").first();
                    self.settings.$topbar.data("index", 0);
                    var topbarContainer = self.settings.$topbar.parent();
                    if (topbarContainer.hasClass("fixed") || topbarContainer.hasClass(self.settings.stickyClass)) {
                        self.settings.$topbar.data("height", self.outerHeight(topbarContainer));
                        self.settings.$topbar.data("stickyoffset", topbarContainer.offset().top)
                    } else {
                        self.settings.$topbar.data("height", self.outerHeight(self.settings.$topbar))
                    }
                    var breakpoint = $("<div class='top-bar-js-breakpoint'/>").insertAfter(self.settings.$topbar);
                    self.settings.breakPoint = breakpoint.width();
                    breakpoint.remove();
                    self.assemble();
                    if (self.settings.is_hover) {
                        self.settings.$topbar.find(".has-dropdown").addClass("not-click")
                    }
                    self.addCustomRule(".f-topbar-fixed { padding-top: " + self.settings.$topbar.data("height") + "px }");
                    if (self.settings.$topbar.parent().hasClass("fixed")) {
                        $("body").addClass("f-topbar-fixed")
                    }
                });
                if (!self.settings.init) {
                    this.events()
                }
                return this.settings.init
            } else {
                return this[method].call(this, options)
            }
        },
        toggle: function() {
            var self = this;
            var topbar = $(".top-bar, [data-topbar]"),
            section = topbar.find("section, .section");
            if (self.breakpoint()) {
                if (!self.rtl) {
                    section.css({
                        left: "0%"
                    });
                    section.find(">.name").css({
                        left: "100%"
                    })
                } else {
                    section.css({
                        right: "0%"
                    });
                    section.find(">.name").css({
                        right: "100%"
                    })
                }
                section.find("li.moved").removeClass("moved");
                topbar.data("index", 0);
                topbar.toggleClass("expanded").css("height", "")
            }
            if (self.settings.scrolltop) {
                if (!topbar.hasClass("expanded")) {
                    if (topbar.hasClass("fixed")) {
                        topbar.parent().addClass("fixed");
                        topbar.removeClass("fixed");
                        $("body").addClass("f-topbar-fixed")
                    }
                } else if (topbar.parent().hasClass("fixed")) {
                    if (self.settings.scrolltop) {
                        topbar.parent().removeClass("fixed");
                        topbar.addClass("fixed");
                        $("body").removeClass("f-topbar-fixed");
                        window.scrollTo(0, 0)
                    } else {
                        topbar.parent().removeClass("expanded")
                    }
                }
            } else {
                if (topbar.parent().hasClass(self.settings.stickyClass)) {
                    topbar.parent().addClass("fixed")
                }
                if (topbar.parent().hasClass("fixed")) {
                    if (!topbar.hasClass("expanded")) {
                        topbar.removeClass("fixed");
                        topbar.parent().removeClass("expanded");
                        self.updateStickyPositioning()
                    } else {
                        topbar.addClass("fixed");
                        topbar.parent().addClass("expanded")
                    }
                }
            }
        },
        timer: null,
        events: function() {
            var self = this;
            $(this.scope).off(".fndtn.topbar").on("click.fndtn.topbar", ".top-bar .toggle-topbar, [data-topbar] .toggle-topbar",
            function(e) {
                e.preventDefault();
                self.toggle()
            }).on("click.fndtn.topbar", ".top-bar li.has-dropdown",
            function(e) {
                var li = $(this),
                target = $(e.target),
                topbar = li.closest("[data-topbar], .top-bar"),
                is_hover = topbar.data("topbar");
                if (target.data("revealId")) {
                    self.toggle();
                    return
                }
                if (self.breakpoint()) return;
                if (self.settings.is_hover && !Modernizr.touch) return;
                e.stopImmediatePropagation();
                if (target[0].nodeName === "A" && target.parent().hasClass("has-dropdown")) {
                    e.preventDefault()
                }
                if (li.hasClass("hover")) {
                    li.removeClass("hover").find("li").removeClass("hover");
                    li.parents("li.hover").removeClass("hover")
                } else {
                    li.addClass("hover")
                }
            }).on("click.fndtn.topbar", ".top-bar .has-dropdown>a, [data-topbar] .has-dropdown>a",
            function(e) {
                if (self.breakpoint() && $(window).width() != self.settings.breakPoint) {
                    e.preventDefault();
                    var $this = $(this),
                    topbar = $this.closest(".top-bar, [data-topbar]"),
                    section = topbar.find("section, .section"),
                    dropdownHeight = $this.next(".dropdown").outerHeight(),
                    $selectedLi = $this.closest("li");
                    topbar.data("index", topbar.data("index") + 1);
                    $selectedLi.addClass("moved");
                    if (!self.rtl) {
                        section.css({
                            left: -(100 * topbar.data("index")) + "%"
                        });
                        section.find(">.name").css({
                            left: 100 * topbar.data("index") + "%"
                        })
                    } else {
                        section.css({
                            right: -(100 * topbar.data("index")) + "%"
                        });
                        section.find(">.name").css({
                            right: 100 * topbar.data("index") + "%"
                        })
                    }
                    topbar.css("height", self.outerHeight($this.siblings("ul"), true) + self.settings.$topbar.data("height"))
                }
            });
            $(window).on("resize.fndtn.topbar",
            function() {
                if (typeof self.settings.$topbar === "undefined") {
                    return
                }
                var stickyContainer = self.settings.$topbar.parent("." + this.settings.stickyClass);
                var stickyOffset;
                if (!self.breakpoint()) {
                    var doToggle = self.settings.$topbar.hasClass("expanded");
                    $(".top-bar, [data-topbar]").css("height", "").removeClass("expanded").find("li").removeClass("hover");
                    if (doToggle) {
                        self.toggle()
                    }
                }
                if (stickyContainer.length > 0) {
                    if (stickyContainer.hasClass("fixed")) {
                        stickyContainer.removeClass("fixed");
                        stickyOffset = stickyContainer.offset().top;
                        if ($(document.body).hasClass("f-topbar-fixed")) {
                            stickyOffset -= self.settings.$topbar.data("height")
                        }
                        self.settings.$topbar.data("stickyoffset", stickyOffset);
                        stickyContainer.addClass("fixed")
                    } else {
                        stickyOffset = stickyContainer.offset().top;
                        self.settings.$topbar.data("stickyoffset", stickyOffset)
                    }
                }
            }.bind(this));
            $("body").on("click.fndtn.topbar",
            function(e) {
                var parent = $(e.target).closest("li").closest("li.hover");
                if (parent.length > 0) {
                    return
                }
                $(".top-bar li, [data-topbar] li").removeClass("hover")
            });
            $(this.scope).on("click.fndtn", ".top-bar .has-dropdown .back, [data-topbar] .has-dropdown .back",
            function(e) {
                e.preventDefault();
                var $this = $(this),
                topbar = $this.closest(".top-bar, [data-topbar]"),
                section = topbar.find("section, .section"),
                $movedLi = $this.closest("li.moved"),
                $previousLevelUl = $movedLi.parent();
                topbar.data("index", topbar.data("index") - 1);
                if (!self.rtl) {
                    section.css({
                        left: -(100 * topbar.data("index")) + "%"
                    });
                    section.find(">.name").css({
                        left: 100 * topbar.data("index") + "%"
                    })
                } else {
                    section.css({
                        right: -(100 * topbar.data("index")) + "%"
                    });
                    section.find(">.name").css({
                        right: 100 * topbar.data("index") + "%"
                    })
                }
                if (topbar.data("index") === 0) {
                    topbar.css("height", "")
                } else {
                    topbar.css("height", self.outerHeight($previousLevelUl, true) + self.settings.$topbar.data("height"))
                }
                setTimeout(function() {
                    $movedLi.removeClass("moved")
                },
                300)
            })
        },
        breakpoint: function() {
            return $(document).width() <= this.settings.breakPoint || $("html").hasClass("lt-ie9")
        },
        assemble: function() {
            var self = this;
            this.settings.$section.detach();
            this.settings.$section.find(".has-dropdown>a").each(function() {
                var $link = $(this),
                $dropdown = $link.siblings(".dropdown"),
                url = $link.attr("href");
                if (self.settings.mobile_show_parent_link && url && url.length > 1) {
                    var $titleLi = $('<li class="title back js-generated"><h5><a href="#"></a></h5></li><li><a class="parent-link js-generated" href="' + url + '">' + $link.text() + "</a></li>")
                } else {
                    var $titleLi = $('<li class="title back js-generated"><h5><a href="#"></a></h5></li>')
                }
                if (self.settings.custom_back_text == true) {
                    $titleLi.find("h5>a").html(self.settings.back_text)
                } else {
                    $titleLi.find("h5>a").html("&laquo; " + $link.html())
                }
                $dropdown.prepend($titleLi)
            });
            this.settings.$section.appendTo(this.settings.$topbar);
            this.sticky()
        },
        height: function(ul) {
            var total = 0,
            self = this;
            ul.find("> li").each(function() {
                total += self.outerHeight($(this), true)
            });
            return total
        },
        sticky: function() {
            var $window = $(window),
            self = this;
            $window.scroll(function() {
                self.updateStickyPositioning()
            })
        },
        updateStickyPositioning: function() {
            var klass = "." + this.settings.stickyClass;
            var $window = $(window);
            if ($(klass).length > 0) {
                var distance = this.settings.$topbar.data("stickyoffset");
                if (!$(klass).hasClass("expanded")) {
                    if ($window.scrollTop() > distance) {
                        if (!$(klass).hasClass("fixed")) {
                            $(klass).addClass("fixed");
                            $("body").addClass("f-topbar-fixed")
                        }
                    } else if ($window.scrollTop() <= distance) {
                        if ($(klass).hasClass("fixed")) {
                            $(klass).removeClass("fixed");
                            $("body").removeClass("f-topbar-fixed")
                        }
                    }
                }
            }
        },
        off: function() {
            $(this.scope).off(".fndtn.topbar");
            $(window).off(".fndtn.topbar")
        },
        reflow: function() {}
    }
})(Foundation.zj, this, this.document); (function($, window, document, undefined) {
    "use strict";
    Foundation.libs.dropdown = {
        name: "dropdown",
        version: "4.3.2",
        settings: {
            activeClass: "open",
            is_hover: false,
            opened: function() {},
            closed: function() {}
        },
        init: function(scope, method, options) {
            this.scope = scope || this.scope;
            Foundation.inherit(this, "throttle scrollLeft data_options");
            if (typeof method === "object") {
                $.extend(true, this.settings, method)
            }
            if (typeof method !== "string") {
                if (!this.settings.init) {
                    this.events()
                }
                return this.settings.init
            } else {
                return this[method].call(this, options)
            }
        },
        events: function() {
            var self = this;
            $(this.scope).on("click.fndtn.dropdown", "[data-dropdown]",
            function(e) {
                var settings = $.extend({},
                self.settings, self.data_options($(this)));
                e.preventDefault();
                if (!settings.is_hover) self.toggle($(this))
            }).on("mouseenter", "[data-dropdown]",
            function(e) {
                var settings = $.extend({},
                self.settings, self.data_options($(this)));
                if (settings.is_hover) self.toggle($(this))
            }).on("mouseleave", "[data-dropdown-content]",
            function(e) {
                var target = $('[data-dropdown="' + $(this).attr("id") + '"]'),
                settings = $.extend({},
                self.settings, self.data_options(target));
                if (settings.is_hover) self.close.call(self, $(this))
            }).on("opened.fndtn.dropdown", "[data-dropdown-content]", this.settings.opened).on("closed.fndtn.dropdown", "[data-dropdown-content]", this.settings.closed);
            $(document).on("click.fndtn.dropdown",
            function(e) {
                var parent = $(e.target).closest("[data-dropdown-content]");
                if ($(e.target).data("dropdown") || $(e.target).parent().data("dropdown")) {
                    return
                }
                if (!$(e.target).data("revealId") && (parent.length > 0 && ($(e.target).is("[data-dropdown-content]") || $.contains(parent.first()[0], e.target)))) {
                    e.stopPropagation();
                    return
                }
                self.close.call(self, $("[data-dropdown-content]"))
            });
            $(window).on("resize.fndtn.dropdown", self.throttle(function() {
                self.resize.call(self)
            },
            50)).trigger("resize");
            this.settings.init = true
        },
        close: function(dropdown) {
            var self = this;
            dropdown.each(function() {
                if ($(this).hasClass(self.settings.activeClass)) {
                    $(this).css(Foundation.rtl ? "right": "left", "-99999px").removeClass(self.settings.activeClass);
                    $(this).trigger("closed")
                }
            })
        },
        open: function(dropdown, target) {
            this.css(dropdown.addClass(this.settings.activeClass), target);
            dropdown.trigger("opened")
        },
        toggle: function(target) {
            var dropdown = $("#" + target.data("dropdown"));
            if (dropdown.length === 0) {
                return
            }
            this.close.call(this, $("[data-dropdown-content]").not(dropdown));
            if (dropdown.hasClass(this.settings.activeClass)) {
                this.close.call(this, dropdown)
            } else {
                this.close.call(this, $("[data-dropdown-content]"));
                this.open.call(this, dropdown, target)
            }
        },
        resize: function() {
            var dropdown = $("[data-dropdown-content].open"),
            target = $("[data-dropdown='" + dropdown.attr("id") + "']");
            if (dropdown.length && target.length) {
                this.css(dropdown, target)
            }
        },
        css: function(dropdown, target) {
            var offset_parent = dropdown.offsetParent();
            var position = target.offset();
            position.top -= offset_parent.offset().top;
            position.left -= offset_parent.offset().left;
            if (this.small()) {
                dropdown.css({
                    position: "absolute",
                    width: "95%",
                    "max-width": "none",
                    top: position.top + this.outerHeight(target)
                });
                dropdown.css(Foundation.rtl ? "right": "left", "2.5%")
            } else {
                if (!Foundation.rtl && $(window).width() > this.outerWidth(dropdown) + target.offset().left && !this.data_options(target).align_right) {
                    var left = position.left;
                    if (dropdown.hasClass("right")) {
                        dropdown.removeClass("right")
                    }
                } else {
                    if (!dropdown.hasClass("right")) {
                        dropdown.addClass("right")
                    }
                    var left = position.left - (this.outerWidth(dropdown) - this.outerWidth(target))
                }
                dropdown.attr("style", "").css({
                    position: "absolute",
                    top: position.top + this.outerHeight(target),
                    left: left
                })
            }
            return dropdown
        },
        small: function() {
            return $(window).width() < 768 || $("html").hasClass("lt-ie9")
        },
        off: function() {
            $(this.scope).off(".fndtn.dropdown");
            $("html, body").off(".fndtn.dropdown");
            $(window).off(".fndtn.dropdown");
            $("[data-dropdown-content]").off(".fndtn.dropdown");
            this.settings.init = false
        },
        reflow: function() {}
    }
})(Foundation.zj, this, this.document);
"use strict"; (function($) {
    var dragging, draggingHeight, placeholders = $();
    $.fn.sortable = function(options) {
        var method = String(options);
        options = $.extend({
            connectWith: false,
            placeholder: null,
            dragImage: null
        },
        options);
        return this.each(function() {
            if (method === "reload") {
                $(this).children(options.items).off("dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s")
            }
            if (/^enable|disable|destroy$/.test(method)) {
                var citems = $(this).children($(this).data("items")).attr("draggable", method === "enable");
                if (method === "destroy") {
                    $(this).off("sortupdate");
                    $(this).removeData("opts");
                    citems.add(this).removeData("connectWith items").off("dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s").off("sortupdate")
                }
                return
            }
            var soptions = $(this).data("opts");
            if (typeof soptions === "undefined") {
                $(this).data("opts", options)
            } else {
                options = soptions
            }
            var isHandle, index, items = $(this).children(options.items);
            var startParent, newParent;
            var placeholder = options.placeholder === null ? $("<" + (/^ul|ol$/i.test(this.tagName) ? "li": "div") + ' class="sortable-placeholder">') : $(options.placeholder).addClass("sortable-placeholder");
            items.find(options.handle).mousedown(function() {
                isHandle = true
            }).mouseup(function() {
                isHandle = false
            });
            $(this).data("items", options.items);
            placeholders = placeholders.add(placeholder);
            if (options.connectWith) {
                $(options.connectWith).add(this).data("connectWith", options.connectWith)
            }
            items.attr("role", "option");
            items.attr("aria-grabbed", "false");
            items.attr("draggable", "true").on("dragstart.h5s",
            function(e) {
                e.stopImmediatePropagation();
                if (options.handle && !isHandle) {
                    return false
                }
                isHandle = false;
                var dt = e.originalEvent.dataTransfer;
                dt.effectAllowed = "move";
                dt.setData("text", "");
                if (options.dragImage && dt.setDragImage) {
                    dt.setDragImage(options.dragImage, 0, 0)
                }
                index = (dragging = $(this)).addClass("sortable-dragging").attr("aria-grabbed", "true").index();
                draggingHeight = dragging.outerHeight();
                startParent = $(this).parent()
            }).on("dragend.h5s",
            function() {
                if (!dragging) {
                    return
                }
                dragging.removeClass("sortable-dragging").attr("aria-grabbed", "false").show();
                placeholders.detach();
                newParent = $(this).parent();
                if (index !== dragging.index() || startParent.get(0) !== newParent.get(0)) {
                    dragging.parent().triggerHandler("sortupdate", {
                        item: dragging,
                        oldindex: index,
                        startparent: startParent,
                        endparent: newParent
                    })
                }
                dragging = null;
                draggingHeight = null
            }).not("a[href], img").on("selectstart.h5s",
            function() {
                if (options.handle && !isHandle) {
                    return true
                }
                if (this.dragDrop) {
                    this.dragDrop()
                }
                return false
            }).end().add([this, placeholder]).on("dragover.h5s dragenter.h5s drop.h5s",
            function(e) {
                if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data("connectWith")) {
                    return true
                }
                if (e.type === "drop") {
                    e.stopPropagation();
                    placeholders.filter(":visible").after(dragging);
                    dragging.trigger("dragend.h5s");
                    return false
                }
                e.preventDefault();
                e.originalEvent.dataTransfer.dropEffect = "move";
                if (items.is(this)) {
                    var thisHeight = $(this).outerHeight();
                    if (options.forcePlaceholderSize) {
                        placeholder.height(draggingHeight)
                    }
                    if (thisHeight > draggingHeight) {
                        var deadZone = thisHeight - draggingHeight,
                        offsetTop = $(this).offset().top;
                        if (placeholder.index() < $(this).index() && e.originalEvent.pageY < offsetTop + deadZone) {
                            return false
                        } else if (placeholder.index() > $(this).index() && e.originalEvent.pageY > offsetTop + thisHeight - deadZone) {
                            return false
                        }
                    }
                    dragging.hide();
                    $(this)[placeholder.index() < $(this).index() ? "after": "before"](placeholder);
                    placeholders.not(placeholder).detach()
                } else if (!placeholders.is(this) && !$(this).children(options.items).length) {
                    placeholders.detach();
                    $(this).append(placeholder)
                }
                return false
            })
        })
    }
})(jQuery); (function($) {
    "use strict";
    var doc = $(document),
    namespace = ".nui",
    $val = $.fn.val,
    actions = window.navigator.pointerEnabled ? {
        start: "pointerdown",
        move: "pointermove",
        end: "pointerup"
    }: window.navigator.msPointerEnabled ? {
        start: "MSPointerDown",
        move: "MSPointerMove",
        end: "MSPointerUp"
    }: {
        start: "mousedown touchstart",
        move: "mousemove touchmove",
        end: "mouseup touchend"
    },
    Classes = ["noUi-target", "noUi-base", "noUi-origin", "noUi-handle", "noUi-horizontal", "noUi-vertical", "noUi-background", "noUi-connect", "noUi-ltr", "noUi-rtl", "noUi-dragable", "", "noUi-state-drag", "", "noUi-state-tap", "noUi-active", "noUi-extended", "noUi-stacking"],
    Formatting = ["decimals", "mark", "thousand", "prefix", "postfix", "encoder", "decoder", "negative", "negativeBefore"],
    FormatDefaults = [2, ".", "", "", "",
    function(a) {
        return a
    },
    function(a) {
        return a
    },
    "-", ""];
    function throwError(message) {
        throw new RangeError("noUiSlider: " + message)
    }
    function throwEqualError(F, a, b) {
        if ((F[a] || F[b]) && F[a] === F[b]) {
            throwError("(Link) '" + a + "' can't match '" + b + "'.'")
        }
    }
    function limit(a) {
        return Math.max(Math.min(a, 100), 0)
    }
    function closest(value, to) {
        return Math.round(value / to) * to
    }
    function subRangeRatio(pa, pb) {
        return 100 / (pb - pa)
    }
    function typeMatch(a, b) {
        return typeof a === typeof b
    }
    function isInstance(a) {
        return a instanceof $ || $["zepto"] && $["zepto"]["isZ"](a)
    }
    function isNumeric(a) {
        return typeof a === "number" && !isNaN(a) && isFinite(a)
    }
    function asArray(a) {
        return $.isArray(a) ? a: [a]
    }
    function addClassFor(element, className, duration) {
        element.addClass(className);
        setTimeout(function() {
            element.removeClass(className)
        },
        duration)
    }
    function getsClass(element, className) {
        var has = element.hasClass(className);
        if (!has) {
            element.addClass(className)
        }
        return has
    }
    function fromPercentage(range, value) {
        return value * 100 / (range[1] - range[0])
    }
    function toPercentage(range, value) {
        return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0])
    }
    function isPercentage(range, value) {
        return value * (range[1] - range[0]) / 100 + range[0]
    }
    function toStepping(options, value) {
        if (value >= options.xVal.slice( - 1)[0]) {
            return 100
        }
        var j = 1,
        va, vb, pa, pb;
        while (value >= options.xVal[j]) {
            j++
        }
        va = options.xVal[j - 1];
        vb = options.xVal[j];
        pa = options.xPct[j - 1];
        pb = options.xPct[j];
        return pa + toPercentage([va, vb], value) / subRangeRatio(pa, pb)
    }
    function fromStepping(options, value) {
        if (value >= 100) {
            return options.xVal.slice( - 1)[0]
        }
        var j = 1,
        va, vb, pa, pb;
        while (value >= options.xPct[j]) {
            j++
        }
        va = options.xVal[j - 1];
        vb = options.xVal[j];
        pa = options.xPct[j - 1];
        pb = options.xPct[j];
        return isPercentage([va, vb], (value - pa) * subRangeRatio(pa, pb))
    }
    function getStep(options, value) {
        var j = 1,
        a, b;
        while (value >= options.xPct[j]) {
            j++
        }
        if (options.snap) {
            a = options.xPct[j - 1];
            b = options.xPct[j];
            if (value - a > (b - a) / 2) {
                return b
            }
            return a
        }
        if (!options.xSteps[j - 1]) {
            return value
        }
        return options.xPct[j - 1] + closest(value - options.xPct[j - 1], options.xSteps[j - 1])
    }
    function fixEvent(e) {
        e.preventDefault();
        var touch = e.type.indexOf("touch") === 0,
        mouse = e.type.indexOf("mouse") === 0,
        pointer = e.type.indexOf("pointer") === 0,
        x,
        y,
        event = e;
        if (e.type.indexOf("MSPointer") === 0) {
            pointer = true
        }
        if (e.originalEvent) {
            e = e.originalEvent
        }
        if (touch) {
            x = e.changedTouches[0].pageX;
            y = e.changedTouches[0].pageY
        }
        if (mouse || pointer) {
            if (!pointer && window.pageXOffset === undefined) {
                window.pageXOffset = document.documentElement.scrollLeft;
                window.pageYOffset = document.documentElement.scrollTop
            }
            x = e.clientX + window.pageXOffset;
            y = e.clientY + window.pageYOffset
        }
        event.points = [x, y];
        event.cursor = mouse;
        return event
    }
    function Format(options) {
        if (options === undefined) {
            options = {}
        }
        if (typeof options !== "object") {
            throwError("(Format) 'format' option must be an object.")
        }
        var settings = {};
        $(Formatting).each(function(i, val) {
            if (options[val] === undefined) {
                settings[val] = FormatDefaults[i]
            } else if (typeMatch(options[val], FormatDefaults[i])) {
                if (val === "decimals") {
                    if (options[val] < 0 || options[val] > 7) {
                        throwError("(Format) 'format.decimals' option must be between 0 and 7.")
                    }
                }
                settings[val] = options[val]
            } else {
                throwError("(Format) 'format." + val + "' must be a " + typeof FormatDefaults[i] + ".")
            }
        });
        throwEqualError(settings, "mark", "thousand");
        throwEqualError(settings, "prefix", "negative");
        throwEqualError(settings, "prefix", "negativeBefore");
        this.settings = settings
    }
    Format.prototype.v = function(a) {
        return this.settings[a]
    };
    Format.prototype.to = function(number) {
        function reverse(a) {
            return a.split("").reverse().join("")
        }
        number = this.v("encoder")(number);
        var negative = "",
        preNegative = "",
        base = "",
        mark = "";
        if (number < 0) {
            negative = this.v("negative");
            preNegative = this.v("negativeBefore")
        }
        number = Math.abs(number).toFixed(this.v("decimals")).toString();
        number = number.split(".");
        if (parseFloat(number) === 0) {
            number[0] = "0"
        }
        if (this.v("thousand")) {
            base = reverse(number[0]).match(/.{1,3}/g);
            base = reverse(base.join(reverse(this.v("thousand"))))
        } else {
            base = number[0]
        }
        if (this.v("mark") && number.length > 1) {
            mark = this.v("mark") + number[1]
        }
        return preNegative + this.v("prefix") + negative + base + mark + this.v("postfix")
    };
    Format.prototype.from = function(input) {
        function esc(s) {
            return s.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g, "\\$&")
        }
        var isNeg;
        if (input === null || input === undefined) {
            return false
        }
        input = input.toString();
        isNeg = input.replace(new RegExp("^" + esc(this.v("negativeBefore"))), "");
        if (input !== isNeg) {
            input = isNeg;
            isNeg = "-"
        } else {
            isNeg = ""
        }
        input = input.replace(new RegExp("^" + esc(this.v("prefix"))), "");
        if (this.v["negative"]) {
            isNeg = "";
            input = input.replace(new RegExp("^" + esc(this.v("negative"))), "-")
        }
        input = input.replace(new RegExp(esc(this.v("postfix")) + "$"), "").replace(new RegExp(esc(this.v("thousand")), "g"), "").replace(this.v("mark"), ".");
        input = this.v("decoder")(parseFloat(isNeg + input));
        if (isNaN(input)) {
            return false
        }
        return input
    };
    function Link(entry, update) {
        if (! (this instanceof Link)) {
            throw new Error("Link: " + "Don't use Link as a function. " + "Use the 'new' keyword.")
        }
        if (!entry) {
            throw new RangeError("Link: missing parameters.")
        }
        this.formatting = entry["format"] || {};
        this.update = !update;
        var that = this,
        target = entry["target"] ||
        function() {},
        method = entry["method"],
        isTooltip = typeof target === "string" && target.indexOf("-tooltip-") === 0,
        isHidden = typeof target === "string" && target.indexOf("-") !== 0,
        isMethod = typeof target === "function",
        is$ = isInstance(target),
        isInput = is$ && target.is("input, select, textarea"),
        methodIsFunction = is$ && typeof method === "function",
        methodIsName = is$ && typeof method === "string" && target[method];
        if (isTooltip) {
            this.method = method || "html";
            this.el = $(target.replace("-tooltip-", "") || "<div/>")[0];
            return
        }
        if (isHidden) {
            this.method = "val";
            this.el = document.createElement("input");
            this.el.name = target;
            this.el.type = "hidden";
            return
        }
        if (isMethod) {
            this.target = false;
            this.method = target;
            return
        }
        if (is$) {
            if (method && (methodIsFunction || methodIsName)) {
                this.target = target;
                this.method = method;
                return
            }
            if (!method && isInput) {
                this.method = "val";
                this.target = target;
                this.target.on("change",
                function(e) {
                    function at(a, b, c) {
                        return [c ? a: b, c ? b: a]
                    }
                    var output = at(null, $(e.target).val(), that.N);
                    that.obj.val(output, {
                        link: that
                    })
                });
                return
            }
            if (!method && !isInput) {
                this.method = "html";
                this.target = target;
                return
            }
        }
        throw new RangeError("Link: Invalid Link.")
    }
    Link.prototype.write = function(options, value, handle, slider, update) {
        if (this.update && update === false) {
            return
        }
        value = fromStepping(options, value);
        value = this.format(value);
        this.saved = value;
        if (typeof this.method === "function") {
            this.method.call(this.target[0] || slider[0], value, handle, slider)
        } else {
            this.target[this.method](value, handle, slider)
        }
    };
    Link.prototype.format = function(a) {
        return this.formatting.to(a)
    };
    Link.prototype.valueOf = function(a) {
        return this.formatting.from(a)
    };
    function testStep(parsed, entry) {
        if (!isNumeric(entry)) {
            throwError("'step' is not numeric.")
        }
        parsed.xSteps[0] = entry
    }
    function testRange(parsed, entry) {
        if (typeof entry !== "object" || $.isArray(entry)) {
            throwError("'range' is not an object.")
        }
        $.each(entry,
        function(index, value) {
            var percentage;
            if (typeof value === "number") {
                value = [value]
            }
            if (!$.isArray(value)) {
                throwError("'range' contains invalid value.")
            }
            if (index === "min") {
                percentage = 0
            } else if (index === "max") {
                percentage = 100
            } else {
                percentage = parseFloat(index)
            }
            if (!isNumeric(percentage) || !isNumeric(value[0])) {
                throwError("'range' value isn't numeric.")
            }
            parsed.xPct.push(percentage);
            parsed.xVal.push(value[0]);
            if (!percentage) {
                if (!isNaN(value[1])) {
                    parsed.xSteps[0] = value[1]
                }
            } else {
                parsed.xSteps.push(isNaN(value[1]) ? false: value[1])
            }
        });
        $.each(parsed.xSteps,
        function(i, n) {
            if (!n) {
                return true
            }
            parsed.xSteps[i] = fromPercentage([parsed.xVal[i], parsed.xVal[i + 1]], n) / subRangeRatio(parsed.xPct[i], parsed.xPct[i + 1])
        })
    }
    function testStart(parsed, entry) {
        if (typeof entry === "number") {
            entry = [entry]
        }
        if (!$.isArray(entry) || !entry.length || entry.length > 2) {
            throwError("'start' option is incorrect.")
        }
        parsed.handles = entry.length;
        parsed.start = entry
    }
    function testSnap(parsed, entry) {
        parsed.snap = entry;
        if (typeof entry !== "boolean") {
            throwError("'snap' option must be a boolean.")
        }
    }
    function testConnect(parsed, entry) {
        if (entry === "lower" && parsed.handles === 1) {
            parsed.connect = 1
        } else if (entry === "upper" && parsed.handles === 1) {
            parsed.connect = 2
        } else if (entry === true && parsed.handles === 2) {
            parsed.connect = 3
        } else if (entry === false) {
            parsed.connect = 0
        } else {
            throwError("'connect' option was doesn't match handle count.")
        }
    }
    function testOrientation(parsed, entry) {
        switch (entry) {
        case "horizontal":
            parsed.ort = 0;
            break;
        case "vertical":
            parsed.ort = 1;
            break;
        default:
            throwError("'orientation' option is invalid.")
        }
    }
    function testMargin(parsed, entry) {
        if (parsed.xPct.length > 2) {
            throwError("'margin' option is only supported on linear sliders.")
        }
        parsed.margin = fromPercentage(parsed.xVal, entry);
        if (!isNumeric(entry)) {
            throwError("'margin' option must be numeric.")
        }
    }
    function testDirection(parsed, entry) {
        switch (entry) {
        case "ltr":
            parsed.dir = 0;
            break;
        case "rtl":
            parsed.dir = 1;
            parsed.connect = [0, 2, 1, 3][parsed.connect];
            break;
        default:
            throwError("'direction' option was not recognized.")
        }
    }
    function testBehaviour(parsed, entry) {
        if (typeof entry !== "string") {
            throwError("'behaviour' must be a string containing options.")
        }
        var tap = entry.indexOf("tap") >= 0,
        extend = entry.indexOf("extend") >= 0,
        drag = entry.indexOf("drag") >= 0,
        fixed = entry.indexOf("fixed") >= 0,
        snap = entry.indexOf("snap") >= 0;
        parsed.events = {
            tap: tap || snap,
            extend: extend,
            drag: drag,
            fixed: fixed,
            snap: snap
        }
    }
    function testSerialization(parsed, entry, sliders) {
        parsed.ser = [entry["lower"], entry["upper"]];
        parsed.formatting = new Format(entry["format"]);
        $.each(parsed.ser,
        function(i, a) {
            if (!$.isArray(a)) {
                throwError("'serialization." + (!i ? "lower": "upper") + "' must be an array.")
            }
            $.each(a,
            function() {
                if (! (this instanceof Link)) {
                    throwError("'serialization." + (!i ? "lower": "upper") + "' can only contain Link instances.")
                }
                this.N = i;
                this.obj = sliders;
                this.scope = this.scope || sliders;
                this.formatting = new Format($.extend({},
                entry["format"], this.formatting))
            })
        });
        if (parsed.dir && parsed.handles > 1) {
            parsed.ser.reverse()
        }
    }
    function test(options, sliders) {
        var parsed = {
            xPct: [],
            xVal: [],
            xSteps: [false],
            margin: 0
        },
        tests;
        tests = {
            step: {
                r: false,
                t: testStep
            },
            range: {
                r: true,
                t: testRange
            },
            start: {
                r: true,
                t: testStart
            },
            snap: {
                r: false,
                t: testSnap
            },
            connect: {
                r: true,
                t: testConnect
            },
            orientation: {
                r: false,
                t: testOrientation
            },
            margin: {
                r: false,
                t: testMargin
            },
            direction: {
                r: true,
                t: testDirection
            },
            behaviour: {
                r: true,
                t: testBehaviour
            },
            serialization: {
                r: true,
                t: testSerialization
            }
        };
        options = $.extend({
            connect: false,
            direction: "ltr",
            behaviour: "tap",
            orientation: "horizontal"
        },
        options);
        options["serialization"] = $.extend({
            lower: [],
            upper: [],
            format: {}
        },
        options["serialization"]);
        $.each(tests,
        function(name, test) {
            if (options[name] === undefined) {
                if (test.r) {
                    throwError("'" + name + "' is required.")
                } else {
                    return true
                }
            }
            test.t(parsed, options[name], sliders)
        });
        parsed.style = parsed.ort ? "top": "left";
        return parsed
    }
    function addHandle(options, index) {
        var handle = $("<div><div/></div>").addClass(Classes[2]),
        additions = ["-lower", "-upper"];
        if (options.dir) {
            additions.reverse()
        }
        handle.children().addClass(Classes[3] + " " + Classes[3] + additions[index]);
        return handle
    }
    function addElement(handle, link) {
        if (link.el) {
            link = new Link({
                target: $(link.el).clone().appendTo(handle),
                method: link.method,
                format: link.formatting
            },
            true)
        }
        return link
    }
    function addElements(elements, handle, formatting) {
        var index, list = [];
        list.push(new Link({
            format: formatting
        },
        true));
        for (index = 0; index < elements.length; index++) {
            list.push(addElement(handle, elements[index]))
        }
        return list
    }
    function addLinks(options, handles) {
        var index, links = [];
        for (index = 0; index < options.handles; index++) {
            links[index] = addElements(options.ser[index], handles[index].children(), options.formatting)
        }
        return links
    }
    function addConnection(connect, target, handles) {
        switch (connect) {
        case 1:
            target.addClass(Classes[7]);
            handles[0].addClass(Classes[6]);
            break;
        case 3:
            handles[1].addClass(Classes[6]);
        case 2:
            handles[0].addClass(Classes[7]);
        case 0:
            target.addClass(Classes[6]);
            break
        }
    }
    function addHandles(options, base) {
        var index, handles = [];
        for (index = 0; index < options.handles; index++) {
            handles.push(addHandle(options, index).appendTo(base))
        }
        return handles
    }
    function addSlider(options, target) {
        target.addClass([Classes[0], Classes[8 + options.dir], Classes[4 + options.ort]].join(" "));
        return $("<div/>").appendTo(target).addClass(Classes[1])
    }
    function closure(target, options, originalOptions) {
        var $Target = $(target),
        $Locations = [ - 1, -1],
        $Base,
        $Serialization,
        $Handles;
        function baseSize() {
            return $Base[["width", "height"][options.ort]]()
        }
        function fireEvents(events) {
            var index, values = [$Target.val()];
            for (index = 0; index < events.length; index++) {
                $Target.trigger(events[index], values)
            }
        }
        function setHandle(handle, to, delimit) {
            var n = handle[0] !== $Handles[0][0] ? 1 : 0,
            lower = $Locations[0] + options.margin,
            upper = $Locations[1] - options.margin;
            if (delimit && $Handles.length > 1) {
                to = n ? Math.max(to, lower) : Math.min(to, upper)
            }
            if (to < 100) {
                to = getStep(options, to)
            }
            to = limit(parseFloat(to.toFixed(7)));
            if (to === $Locations[n]) {
                if ($Handles.length === 1) {
                    return false
                }
                return to === lower || to === upper ? 0 : false
            }
            handle.css(options.style, to + "%");
            if (handle.is(":first-child")) {
                handle.toggleClass(Classes[17], to > 50)
            }
            $Locations[n] = to;
            if (options.dir) {
                to = 100 - to
            }
            $($Serialization[n]).each(function() {
                this.write(options, to, handle.children(), $Target)
            });
            return true
        }
        function getPositions(a, b, delimit) {
            var c = a + b[0],
            d = a + b[1];
            if (delimit) {
                if (c < 0) {
                    d += Math.abs(c)
                }
                if (d > 100) {
                    c -= d - 100
                }
                return [limit(c), limit(d)]
            }
            return [c, d]
        }
        function jump(handle, to, instant) {
            if (!instant) {
                addClassFor($Target, Classes[14], 300)
            }
            setHandle(handle, to, false);
            fireEvents(["slide", "set", "change"])
        }
        function attach(events, element, callback, data) {
            events = events.replace(/\s/g, namespace + " ") + namespace;
            return element.on(events,
            function(e) {
                var disabled = $Target.attr("disabled");
                disabled = !(disabled === undefined || disabled === null);
                if ($Target.hasClass(Classes[14]) || disabled) {
                    return false
                }
                e = fixEvent(e);
                e.calcPoint = e.points[options.ort];
                callback(e, data)
            })
        }
        function move(event, data) {
            var handles = data.handles || $Handles,
            positions, state = false,
            proposal = (event.calcPoint - data.start) * 100 / baseSize(),
            h = handles[0][0] !== $Handles[0][0] ? 1 : 0;
            positions = getPositions(proposal, data.positions, handles.length > 1);
            state = setHandle(handles[0], positions[h], handles.length === 1);
            if (handles.length > 1) {
                state = setHandle(handles[1], positions[h ? 0 : 1], false) || state
            }
            if (state) {
                fireEvents(["slide"])
            }
        }
        function end(event) {
            $("." + Classes[15]).removeClass(Classes[15]);
            if (event.cursor) {
                $("body").css("cursor", "").off(namespace)
            }
            doc.off(namespace);
            $Target.removeClass(Classes[12]);
            fireEvents(["set", "change"])
        }
        function start(event, data) {
            if (data.handles.length === 1) {
                data.handles[0].children().addClass(Classes[15])
            }
            event.stopPropagation();
            attach(actions.move, doc, move, {
                start: event.calcPoint,
                handles: data.handles,
                positions: [$Locations[0], $Locations[$Handles.length - 1]]
            });
            attach(actions.end, doc, end, null);
            if (event.cursor) {
                $("body").css("cursor", $(event.target).css("cursor"));
                if ($Handles.length > 1) {
                    $Target.addClass(Classes[12])
                }
                $("body").on("selectstart" + namespace, false)
            }
        }
        function tap(event) {
            var location = event.calcPoint,
            total = 0,
            to;
            event.stopPropagation();
            $.each($Handles,
            function() {
                total += this.offset()[options.style]
            });
            total = location < total / 2 || $Handles.length === 1 ? 0 : 1;
            location -= $Base.offset()[options.style];
            to = location * 100 / baseSize();
            jump($Handles[total], to, options.events.snap);
            if (options.events.snap) {
                start(event, {
                    handles: [$Handles[total]]
                })
            }
        }
        function edge(event) {
            var i = event.calcPoint < $Base.offset()[options.style],
            to = i ? 0 : 100;
            i = i ? 0 : $Handles.length - 1;
            jump($Handles[i], to, false)
        }
        function events(behaviour) {
            var i, drag;
            if (!behaviour.fixed) {
                for (i = 0; i < $Handles.length; i++) {
                    attach(actions.start, $Handles[i].children(), start, {
                        handles: [$Handles[i]]
                    })
                }
            }
            if (behaviour.tap) {
                attach(actions.start, $Base, tap, {
                    handles: $Handles
                })
            }
            if (behaviour.extend) {
                $Target.addClass(Classes[16]);
                if (behaviour.tap) {
                    attach(actions.start, $Target, edge, {
                        handles: $Handles
                    })
                }
            }
            if (behaviour.drag) {
                drag = $Base.find("." + Classes[7]).addClass(Classes[10]);
                if (behaviour.fixed) {
                    drag = drag.add($Base.children().not(drag).children())
                }
                attach(actions.start, drag, start, {
                    handles: $Handles
                })
            }
        }
        if (!$Target.is(":empty")) {
            throw new Error("Slider was already initialized.")
        }
        $Base = addSlider(options, $Target);
        $Handles = addHandles(options, $Base);
        $Serialization = addLinks(options, $Handles);
        addConnection(options.connect, $Target, $Handles);
        events(options.events);
        target.vSet = function(values, callback, link, update, animate) {
            var i, to;
            if (options.dir && options.handles > 1) {
                values.reverse()
            }
            if (animate) {
                addClassFor($Target, Classes[14], 300)
            }
            for (i = 0; i < ($Handles.length > 1 ? 3 : 1); i++) {
                to = link || $Serialization[i % 2][0];
                to = to.valueOf(values[i % 2]);
                if (to === false) {
                    continue
                }
                to = toStepping(options, to);
                if (options.dir) {
                    to = 100 - to
                }
                if (setHandle($Handles[i % 2], to, true) === true) {
                    continue
                }
                $($Serialization[i % 2]).each(function() {
                    this.write(options, $Locations[i % 2], $Handles[i % 2].children(), $Target, update)
                })
            }
            if (callback === true) {
                fireEvents(["set"])
            }
            return this
        };
        target.vGet = function() {
            var i, retour = [];
            for (i = 0; i < options.handles; i++) {
                retour[i] = $Serialization[i][0].saved
            }
            if (retour.length === 1) {
                return retour[0]
            }
            if (options.dir && options.handles > 1) {
                return retour.reverse()
            }
            return retour
        };
        target.destroy = function() {
            $.each($Serialization,
            function() {
                $.each(this,
                function() {
                    if (this.target) {
                        this.target.off(namespace)
                    }
                })
            });
            $(this).off(namespace).removeClass(Classes.join(" ")).empty();
            return originalOptions
        };
        $Target.val(options.start)
    }
    function initialize(originalOptions) {
        if (!this.length) {
            throwError("Can't initialize slider on empty selection.")
        }
        var options = test(originalOptions, this);
        return this.each(function() {
            closure(this, options, originalOptions)
        })
    }
    function rebuild(options) {
        return this.each(function() {
            var values = $(this).val(),
            originalOptions = this.destroy(),
            newOptions = $.extend({},
            originalOptions, options);
            $(this).noUiSlider(newOptions);
            if (originalOptions.start === newOptions.start) {
                $(this).val(values)
            }
        })
    }
    $.noUiSlider = {
        Link: Link
    };
    $.fn.noUiSlider = function(options, re) {
        return (re ? rebuild: initialize).call(this, options)
    };
    $.fn.val = function() {
        var args = Array.prototype.slice.call(arguments, 0),
        set,
        link,
        update,
        animate;
        if (!args.length) {
            if (this.hasClass(Classes[0])) {
                return this[0].vGet()
            }
            return $val.apply(this)
        }
        if (typeof args[1] === "object") {
            set = args[1]["set"];
            link = args[1]["link"];
            update = args[1]["update"];
            animate = args[1]["animate"]
        } else if (args[1] === true) {
            set = true
        }
        return this.each(function() {
            if ($(this).hasClass(Classes[0])) {
                this.vSet(asArray(args[0]), set, link, update, animate)
            } else {
                $val.apply($(this), args)
            }
        })
    }
})(window["jQuery"] || window["Zepto"]); (function(window, angular, undefined) {
    "use strict";
    var $sanitizeMinErr = angular.$$minErr("$sanitize");
    var $sanitize = function(html) {
        var buf = [];
        htmlParser(html, htmlSanitizeWriter(buf));
        return buf.join("")
    };
    var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
    END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
    ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
    BEGIN_TAG_REGEXP = /^</,
    BEGING_END_TAGE_REGEXP = /^<\s*\//,
    COMMENT_REGEXP = /<!--(.*?)-->/g,
    DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
    CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
    URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/i,
    NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
    var voidElements = makeMap("area,br,col,hr,img,wbr");
    var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
    optionalEndTagInlineElements = makeMap("rp,rt"),
    optionalEndTagElements = angular.extend({},
    optionalEndTagInlineElements, optionalEndTagBlockElements);
    var blockElements = angular.extend({},
    optionalEndTagBlockElements, makeMap("address,article,aside," + "blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6," + "header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
    var inlineElements = angular.extend({},
    optionalEndTagInlineElements, makeMap("a,abbr,acronym,b,bdi,bdo," + "big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small," + "span,strike,strong,sub,sup,time,tt,u,var"));
    var specialElements = makeMap("script,style");
    var validElements = angular.extend({},
    voidElements, blockElements, inlineElements, optionalEndTagElements);
    var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
    var validAttrs = angular.extend({},
    uriAttrs, makeMap("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear," + "color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace," + "ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules," + "scope,scrolling,shape,span,start,summary,target,title,type," + "valign,value,vspace,width"));
    function makeMap(str) {
        var obj = {},
        items = str.split(","),
        i;
        for (i = 0; i < items.length; i++) obj[items[i]] = true;
        return obj
    }
    function htmlParser(html, handler) {
        var index, chars, match, stack = [],
        last = html;
        stack.last = function() {
            return stack[stack.length - 1]
        };
        while (html) {
            chars = true;
            if (!stack.last() || !specialElements[stack.last()]) {
                if (html.indexOf("<!--") === 0) {
                    index = html.indexOf("--", 4);
                    if (index >= 0 && html.lastIndexOf("-->", index) === index) {
                        if (handler.comment) handler.comment(html.substring(4, index));
                        html = html.substring(index + 3);
                        chars = false
                    }
                } else if (DOCTYPE_REGEXP.test(html)) {
                    match = html.match(DOCTYPE_REGEXP);
                    if (match) {
                        html = html.replace(match[0], "");
                        chars = false
                    }
                } else if (BEGING_END_TAGE_REGEXP.test(html)) {
                    match = html.match(END_TAG_REGEXP);
                    if (match) {
                        html = html.substring(match[0].length);
                        match[0].replace(END_TAG_REGEXP, parseEndTag);
                        chars = false
                    }
                } else if (BEGIN_TAG_REGEXP.test(html)) {
                    match = html.match(START_TAG_REGEXP);
                    if (match) {
                        html = html.substring(match[0].length);
                        match[0].replace(START_TAG_REGEXP, parseStartTag);
                        chars = false
                    }
                }
                if (chars) {
                    index = html.indexOf("<");
                    var text = index < 0 ? html: html.substring(0, index);
                    html = index < 0 ? "": html.substring(index);
                    if (handler.chars) handler.chars(decodeEntities(text))
                }
            } else {
                html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", "i"),
                function(all, text) {
                    text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
                    if (handler.chars) handler.chars(decodeEntities(text));
                    return ""
                });
                parseEndTag("", stack.last())
            }
            if (html == last) {
                throw $sanitizeMinErr("badparse", "The sanitizer was unable to parse the following block of html: {0}", html)
            }
            last = html
        }
        parseEndTag();
        function parseStartTag(tag, tagName, rest, unary) {
            tagName = angular.lowercase(tagName);
            if (blockElements[tagName]) {
                while (stack.last() && inlineElements[stack.last()]) {
                    parseEndTag("", stack.last())
                }
            }
            if (optionalEndTagElements[tagName] && stack.last() == tagName) {
                parseEndTag("", tagName)
            }
            unary = voidElements[tagName] || !!unary;
            if (!unary) stack.push(tagName);
            var attrs = {};
            rest.replace(ATTR_REGEXP,
            function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
                var value = doubleQuotedValue || singleQuotedValue || unquotedValue || "";
                attrs[name] = decodeEntities(value)
            });
            if (handler.start) handler.start(tagName, attrs, unary)
        }
        function parseEndTag(tag, tagName) {
            var pos = 0,
            i;
            tagName = angular.lowercase(tagName);
            if (tagName) for (pos = stack.length - 1; pos >= 0; pos--) if (stack[pos] == tagName) break;
            if (pos >= 0) {
                for (i = stack.length - 1; i >= pos; i--) if (handler.end) handler.end(stack[i]);
                stack.length = pos
            }
        }
    }
    var hiddenPre = document.createElement("pre");
    function decodeEntities(value) {
        hiddenPre.innerHTML = value.replace(/</g, "&lt;");
        return hiddenPre.innerText || hiddenPre.textContent || ""
    }
    function encodeEntities(value) {
        return value.replace(/&/g, "&amp;").replace(NON_ALPHANUMERIC_REGEXP,
        function(value) {
            return "&#" + value.charCodeAt(0) + ";"
        }).replace(/</g, "&lt;").replace(/>/g, "&gt;")
    }
    function htmlSanitizeWriter(buf) {
        var ignore = false;
        var out = angular.bind(buf, buf.push);
        return {
            start: function(tag, attrs, unary) {
                tag = angular.lowercase(tag);
                if (!ignore && specialElements[tag]) {
                    ignore = tag
                }
                if (!ignore && validElements[tag] == true) {
                    out("<");
                    out(tag);
                    angular.forEach(attrs,
                    function(value, key) {
                        var lkey = angular.lowercase(key);
                        if (validAttrs[lkey] == true && (uriAttrs[lkey] !== true || value.match(URI_REGEXP))) {
                            out(" ");
                            out(key);
                            out('="');
                            out(encodeEntities(value));
                            out('"')
                        }
                    });
                    out(unary ? "/>": ">")
                }
            },
            end: function(tag) {
                tag = angular.lowercase(tag);
                if (!ignore && validElements[tag] == true) {
                    out("</");
                    out(tag);
                    out(">")
                }
                if (tag == ignore) {
                    ignore = false
                }
            },
            chars: function(chars) {
                if (!ignore) {
                    out(encodeEntities(chars))
                }
            }
        }
    }
    angular.module("ngSanitize", []).value("$sanitize", $sanitize);
    angular.module("ngSanitize").filter("linky",
    function() {
        var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,
        MAILTO_REGEXP = /^mailto:/;
        return function(text, target) {
            if (!text) return text;
            var match;
            var raw = text;
            var html = [];
            var writer = htmlSanitizeWriter(html);
            var url;
            var i;
            var properties = {};
            if (angular.isDefined(target)) {
                properties.target = target
            }
            while (match = raw.match(LINKY_URL_REGEXP)) {
                url = match[0];
                if (match[2] == match[3]) url = "mailto:" + url;
                i = match.index;
                writer.chars(raw.substr(0, i));
                properties.href = url;
                writer.start("a", properties);
                writer.chars(match[0].replace(MAILTO_REGEXP, ""));
                writer.end("a");
                raw = raw.substring(i + match[0].length)
            }
            writer.chars(raw);
            return html.join("")
        }
    })
})(window, window.angular); (function($) {
    $.flexslider = function(el, options) {
        var slider = $(el);
        slider.vars = $.extend({},
        $.flexslider.defaults, options);
        var namespace = slider.vars.namespace,
        msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
        touch = ("ontouchstart" in window || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch,
        eventType = "click touchend MSPointerUp",
        watchedEvent = "",
        watchedEventClearTimer,
        vertical = slider.vars.direction === "vertical",
        reverse = slider.vars.reverse,
        carousel = slider.vars.itemWidth > 0,
        fade = slider.vars.animation === "fade",
        asNav = slider.vars.asNavFor !== "",
        methods = {},
        focused = true;
        $.data(el, "flexslider", slider);
        methods = {
            init: function() {
                slider.animating = false;
                slider.currentSlide = parseInt(slider.vars.startAt ? slider.vars.startAt: 0, 10);
                if (isNaN(slider.currentSlide)) slider.currentSlide = 0;
                slider.animatingTo = slider.currentSlide;
                slider.atEnd = slider.currentSlide === 0 || slider.currentSlide === slider.last;
                slider.containerSelector = slider.vars.selector.substr(0, slider.vars.selector.search(" "));
                slider.slides = $(slider.vars.selector, slider);
                slider.container = $(slider.containerSelector, slider);
                slider.count = slider.slides.length;
                slider.syncExists = $(slider.vars.sync).length > 0;
                if (slider.vars.animation === "slide") slider.vars.animation = "swing";
                slider.prop = vertical ? "top": "marginLeft";
                slider.args = {};
                slider.manualPause = false;
                slider.stopped = false;
                slider.started = false;
                slider.startTimeout = null;
                slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS &&
                function() {
                    var obj = document.createElement("div"),
                    props = ["perspectiveProperty", "WebkitPerspective", "MozPerspective", "OPerspective", "msPerspective"];
                    for (var i in props) {
                        if (obj.style[props[i]] !== undefined) {
                            slider.pfx = props[i].replace("Perspective", "").toLowerCase();
                            slider.prop = "-" + slider.pfx + "-transform";
                            return true
                        }
                    }
                    return false
                } ();
                if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer);
                if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls);
                if (slider.vars.randomize) {
                    slider.slides.sort(function() {
                        return Math.round(Math.random()) - .5
                    });
                    slider.container.empty().append(slider.slides)
                }
                slider.doMath();
                slider.setup("init");
                if (slider.vars.controlNav) methods.controlNav.setup();
                if (slider.vars.directionNav) methods.directionNav.setup();
                if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) {
                    $(document).bind("keyup",
                    function(event) {
                        var keycode = event.keyCode;
                        if (!slider.animating && (keycode === 39 || keycode === 37)) {
                            var target = keycode === 39 ? slider.getTarget("next") : keycode === 37 ? slider.getTarget("prev") : false;
                            slider.flexAnimate(target, slider.vars.pauseOnAction)
                        }
                    })
                }
                if (slider.vars.mousewheel) {
                    slider.bind("mousewheel",
                    function(event, delta, deltaX, deltaY) {
                        event.preventDefault();
                        var target = delta < 0 ? slider.getTarget("next") : slider.getTarget("prev");
                        slider.flexAnimate(target, slider.vars.pauseOnAction)
                    })
                }
                if (slider.vars.pausePlay) methods.pausePlay.setup();
                if (slider.vars.slideshow && slider.vars.pauseInvisible) methods.pauseInvisible.init();
                if (slider.vars.slideshow) {
                    if (slider.vars.pauseOnHover) {
                        slider.hover(function() {
                            if (!slider.manualPlay && !slider.manualPause) slider.pause()
                        },
                        function() {
                            if (!slider.manualPause && !slider.manualPlay && !slider.stopped) slider.play()
                        })
                    }
                    if (!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) {
                        slider.vars.initDelay > 0 ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play()
                    }
                }
                if (asNav) methods.asNav.setup();
                if (touch && slider.vars.touch) methods.touch();
                if (!fade || fade && slider.vars.smoothHeight) $(window).bind("resize orientationchange focus", methods.resize);
                slider.find("img").attr("draggable", "false");
                setTimeout(function() {
                    slider.vars.start(slider)
                },
                200)
            },
            asNav: {
                setup: function() {
                    slider.asNav = true;
                    slider.animatingTo = Math.floor(slider.currentSlide / slider.move);
                    slider.currentItem = slider.currentSlide;
                    slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide");
                    if (!msGesture) {
                        slider.slides.on(eventType,
                        function(e) {
                            e.preventDefault();
                            var $slide = $(this),
                            target = $slide.index();
                            var posFromLeft = $slide.offset().left - $(slider).scrollLeft();
                            if (posFromLeft <= 0 && $slide.hasClass(namespace + "active-slide")) {
                                slider.flexAnimate(slider.getTarget("prev"), true)
                            } else if (!$(slider.vars.asNavFor).data("flexslider").animating && !$slide.hasClass(namespace + "active-slide")) {
                                slider.direction = slider.currentItem < target ? "next": "prev";
                                slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true)
                            }
                        })
                    } else {
                        el._slider = slider;
                        slider.slides.each(function() {
                            var that = this;
                            that._gesture = new MSGesture;
                            that._gesture.target = that;
                            that.addEventListener("MSPointerDown",
                            function(e) {
                                e.preventDefault();
                                if (e.currentTarget._gesture) e.currentTarget._gesture.addPointer(e.pointerId)
                            },
                            false);
                            that.addEventListener("MSGestureTap",
                            function(e) {
                                e.preventDefault();
                                var $slide = $(this),
                                target = $slide.index();
                                if (!$(slider.vars.asNavFor).data("flexslider").animating && !$slide.hasClass("active")) {
                                    slider.direction = slider.currentItem < target ? "next": "prev";
                                    slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true)
                                }
                            })
                        })
                    }
                }
            },
            controlNav: {
                setup: function() {
                    if (!slider.manualControls) {
                        methods.controlNav.setupPaging()
                    } else {
                        methods.controlNav.setupManual()
                    }
                },
                setupPaging: function() {
                    var type = slider.vars.controlNav === "thumbnails" ? "control-thumbs": "control-paging",
                    j = 1,
                    item,
                    slide;
                    slider.controlNavScaffold = $('<ol class="' + namespace + "control-nav " + namespace + type + '"></ol>');
                    if (slider.pagingCount > 1) {
                        for (var i = 0; i < slider.pagingCount; i++) {
                            slide = slider.slides.eq(i);
                            item = slider.vars.controlNav === "thumbnails" ? '<img src="' + slide.attr("data-thumb") + '"/>': "<a>" + j + "</a>";
                            if ("thumbnails" === slider.vars.controlNav && true === slider.vars.thumbCaptions) {
                                var captn = slide.attr("data-thumbcaption");
                                if ("" != captn && undefined != captn) item += '<span class="' + namespace + 'caption">' + captn + "</span>"
                            }
                            slider.controlNavScaffold.append("<li>" + item + "</li>");
                            j++
                        }
                    }
                    slider.controlsContainer ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold);
                    methods.controlNav.set();
                    methods.controlNav.active();
                    slider.controlNavScaffold.delegate("a, img", eventType,
                    function(event) {
                        event.preventDefault();
                        if (watchedEvent === "" || watchedEvent === event.type) {
                            var $this = $(this),
                            target = slider.controlNav.index($this);
                            if (!$this.hasClass(namespace + "active")) {
                                slider.direction = target > slider.currentSlide ? "next": "prev";
                                slider.flexAnimate(target, slider.vars.pauseOnAction)
                            }
                        }
                        if (watchedEvent === "") {
                            watchedEvent = event.type
                        }
                        methods.setToClearWatchedEvent()
                    })
                },
                setupManual: function() {
                    slider.controlNav = slider.manualControls;
                    methods.controlNav.active();
                    slider.controlNav.bind(eventType,
                    function(event) {
                        event.preventDefault();
                        if (watchedEvent === "" || watchedEvent === event.type) {
                            var $this = $(this),
                            target = slider.controlNav.index($this);
                            if (!$this.hasClass(namespace + "active")) {
                                target > slider.currentSlide ? slider.direction = "next": slider.direction = "prev";
                                slider.flexAnimate(target, slider.vars.pauseOnAction)
                            }
                        }
                        if (watchedEvent === "") {
                            watchedEvent = event.type
                        }
                        methods.setToClearWatchedEvent()
                    })
                },
                set: function() {
                    var selector = slider.vars.controlNav === "thumbnails" ? "img": "a";
                    slider.controlNav = $("." + namespace + "control-nav li " + selector, slider.controlsContainer ? slider.controlsContainer: slider)
                },
                active: function() {
                    slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active")
                },
                update: function(action, pos) {
                    if (slider.pagingCount > 1 && action === "add") {
                        slider.controlNavScaffold.append($("<li><a>" + slider.count + "</a></li>"))
                    } else if (slider.pagingCount === 1) {
                        slider.controlNavScaffold.find("li").remove()
                    } else {
                        slider.controlNav.eq(pos).closest("li").remove()
                    }
                    methods.controlNav.set();
                    slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length ? slider.update(pos, action) : methods.controlNav.active()
                }
            },
            directionNav: {
                setup: function() {
                    var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">' + slider.vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + "</a></li></ul>");
                    if (slider.controlsContainer) {
                        $(slider.controlsContainer).append(directionNavScaffold);
                        slider.directionNav = $("." + namespace + "direction-nav li a", slider.controlsContainer)
                    } else {
                        slider.append(directionNavScaffold);
                        slider.directionNav = $("." + namespace + "direction-nav li a", slider)
                    }
                    methods.directionNav.update();
                    slider.directionNav.bind(eventType,
                    function(event) {
                        event.preventDefault();
                        var target;
                        if (watchedEvent === "" || watchedEvent === event.type) {
                            target = $(this).hasClass(namespace + "next") ? slider.getTarget("next") : slider.getTarget("prev");
                            slider.flexAnimate(target, slider.vars.pauseOnAction)
                        }
                        if (watchedEvent === "") {
                            watchedEvent = event.type
                        }
                        methods.setToClearWatchedEvent()
                    })
                },
                update: function() {
                    var disabledClass = namespace + "disabled";
                    if (slider.pagingCount === 1) {
                        slider.directionNav.addClass(disabledClass).attr("tabindex", "-1")
                    } else if (!slider.vars.animationLoop) {
                        if (slider.animatingTo === 0) {
                            slider.directionNav.removeClass(disabledClass).filter("." + namespace + "prev").addClass(disabledClass).attr("tabindex", "-1")
                        } else if (slider.animatingTo === slider.last) {
                            slider.directionNav.removeClass(disabledClass).filter("." + namespace + "next").addClass(disabledClass).attr("tabindex", "-1")
                        } else {
                            slider.directionNav.removeClass(disabledClass).removeAttr("tabindex")
                        }
                    } else {
                        slider.directionNav.removeClass(disabledClass).removeAttr("tabindex")
                    }
                }
            },
            pausePlay: {
                setup: function() {
                    var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>');
                    if (slider.controlsContainer) {
                        slider.controlsContainer.append(pausePlayScaffold);
                        slider.pausePlay = $("." + namespace + "pauseplay a", slider.controlsContainer)
                    } else {
                        slider.append(pausePlayScaffold);
                        slider.pausePlay = $("." + namespace + "pauseplay a", slider)
                    }
                    methods.pausePlay.update(slider.vars.slideshow ? namespace + "pause": namespace + "play");
                    slider.pausePlay.bind(eventType,
                    function(event) {
                        event.preventDefault();
                        if (watchedEvent === "" || watchedEvent === event.type) {
                            if ($(this).hasClass(namespace + "pause")) {
                                slider.manualPause = true;
                                slider.manualPlay = false;
                                slider.pause()
                            } else {
                                slider.manualPause = false;
                                slider.manualPlay = true;
                                slider.play()
                            }
                        }
                        if (watchedEvent === "") {
                            watchedEvent = event.type
                        }
                        methods.setToClearWatchedEvent()
                    })
                },
                update: function(state) {
                    state === "play" ? slider.pausePlay.removeClass(namespace + "pause").addClass(namespace + "play").html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + "play").addClass(namespace + "pause").html(slider.vars.pauseText)
                }
            },
            touch: function() {
                var startX, startY, offset, cwidth, dx, startT, scrolling = false,
                localX = 0,
                localY = 0,
                accDx = 0;
                if (!msGesture) {
                    el.addEventListener("touchstart", onTouchStart, false);
                    function onTouchStart(e) {
                        if (slider.animating) {
                            e.preventDefault()
                        } else if (window.navigator.msPointerEnabled || e.touches.length === 1) {
                            slider.pause();
                            cwidth = vertical ? slider.h: slider.w;
                            startT = Number(new Date);
                            localX = e.touches[0].pageX;
                            localY = e.touches[0].pageY;
                            offset = carousel && reverse && slider.animatingTo === slider.last ? 0 : carousel && reverse ? slider.limit - (slider.itemW + slider.vars.itemMargin) * slider.move * slider.animatingTo: carousel && slider.currentSlide === slider.last ? slider.limit: carousel ? (slider.itemW + slider.vars.itemMargin) * slider.move * slider.currentSlide: reverse ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth: (slider.currentSlide + slider.cloneOffset) * cwidth;
                            startX = vertical ? localY: localX;
                            startY = vertical ? localX: localY;
                            el.addEventListener("touchmove", onTouchMove, false);
                            el.addEventListener("touchend", onTouchEnd, false)
                        }
                    }
                    function onTouchMove(e) {
                        localX = e.touches[0].pageX;
                        localY = e.touches[0].pageY;
                        dx = vertical ? startX - localY: startX - localX;
                        scrolling = vertical ? Math.abs(dx) < Math.abs(localX - startY) : Math.abs(dx) < Math.abs(localY - startY);
                        var fxms = 500;
                        if (!scrolling || Number(new Date) - startT > fxms) {
                            e.preventDefault();
                            if (!fade && slider.transitions) {
                                if (!slider.vars.animationLoop) {
                                    dx = dx / (slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0 ? Math.abs(dx) / cwidth + 2 : 1)
                                }
                                slider.setProps(offset + dx, "setTouch")
                            }
                        }
                    }
                    function onTouchEnd(e) {
                        el.removeEventListener("touchmove", onTouchMove, false);
                        if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
                            var updateDx = reverse ? -dx: dx,
                            target = updateDx > 0 ? slider.getTarget("next") : slider.getTarget("prev");
                            if (slider.canAdvance(target) && (Number(new Date) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth / 2)) {
                                slider.flexAnimate(target, slider.vars.pauseOnAction)
                            } else {
                                if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true)
                            }
                        }
                        el.removeEventListener("touchend", onTouchEnd, false);
                        startX = null;
                        startY = null;
                        dx = null;
                        offset = null
                    }
                } else {
                    el.style.msTouchAction = "none";
                    el._gesture = new MSGesture;
                    el._gesture.target = el;
                    el.addEventListener("MSPointerDown", onMSPointerDown, false);
                    el._slider = slider;
                    el.addEventListener("MSGestureChange", onMSGestureChange, false);
                    el.addEventListener("MSGestureEnd", onMSGestureEnd, false);
                    function onMSPointerDown(e) {
                        e.stopPropagation();
                        if (slider.animating) {
                            e.preventDefault()
                        } else {
                            slider.pause();
                            el._gesture.addPointer(e.pointerId);
                            accDx = 0;
                            cwidth = vertical ? slider.h: slider.w;
                            startT = Number(new Date);
                            offset = carousel && reverse && slider.animatingTo === slider.last ? 0 : carousel && reverse ? slider.limit - (slider.itemW + slider.vars.itemMargin) * slider.move * slider.animatingTo: carousel && slider.currentSlide === slider.last ? slider.limit: carousel ? (slider.itemW + slider.vars.itemMargin) * slider.move * slider.currentSlide: reverse ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth: (slider.currentSlide + slider.cloneOffset) * cwidth
                        }
                    }
                    function onMSGestureChange(e) {
                        e.stopPropagation();
                        var slider = e.target._slider;
                        if (!slider) {
                            return
                        }
                        var transX = -e.translationX,
                        transY = -e.translationY;
                        accDx = accDx + (vertical ? transY: transX);
                        dx = accDx;
                        scrolling = vertical ? Math.abs(accDx) < Math.abs( - transX) : Math.abs(accDx) < Math.abs( - transY);
                        if (e.detail === e.MSGESTURE_FLAG_INERTIA) {
                            setImmediate(function() {
                                el._gesture.stop()
                            });
                            return
                        }
                        if (!scrolling || Number(new Date) - startT > 500) {
                            e.preventDefault();
                            if (!fade && slider.transitions) {
                                if (!slider.vars.animationLoop) {
                                    dx = accDx / (slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0 ? Math.abs(accDx) / cwidth + 2 : 1)
                                }
                                slider.setProps(offset + dx, "setTouch")
                            }
                        }
                    }
                    function onMSGestureEnd(e) {
                        e.stopPropagation();
                        var slider = e.target._slider;
                        if (!slider) {
                            return
                        }
                        if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
                            var updateDx = reverse ? -dx: dx,
                            target = updateDx > 0 ? slider.getTarget("next") : slider.getTarget("prev");
                            if (slider.canAdvance(target) && (Number(new Date) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth / 2)) {
                                slider.flexAnimate(target, slider.vars.pauseOnAction)
                            } else {
                                if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true)
                            }
                        }
                        startX = null;
                        startY = null;
                        dx = null;
                        offset = null;
                        accDx = 0
                    }
                }
            },
            resize: function() {
                if (!slider.animating && slider.is(":visible")) {
                    if (!carousel) slider.doMath();
                    if (fade) {
                        methods.smoothHeight()
                    } else if (carousel) {
                        slider.slides.width(slider.computedW);
                        slider.update(slider.pagingCount);
                        slider.setProps()
                    } else if (vertical) {
                        slider.viewport.height(slider.h);
                        slider.setProps(slider.h, "setTotal")
                    } else {
                        if (slider.vars.smoothHeight) methods.smoothHeight();
                        slider.newSlides.width(slider.computedW);
                        slider.setProps(slider.computedW, "setTotal")
                    }
                }
            },
            smoothHeight: function(dur) {
                if (!vertical || fade) {
                    var $obj = fade ? slider: slider.viewport;
                    dur ? $obj.animate({
                        height: slider.slides.eq(slider.animatingTo).height()
                    },
                    dur) : $obj.height(slider.slides.eq(slider.animatingTo).height())
                }
            },
            sync: function(action) {
                var $obj = $(slider.vars.sync).data("flexslider"),
                target = slider.animatingTo;
                switch (action) {
                case "animate":
                    $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true);
                    break;
                case "play":
                    if (!$obj.playing && !$obj.asNav) {
                        $obj.play()
                    }
                    break;
                case "pause":
                    $obj.pause();
                    break
                }
            },
            uniqueID: function($clone) {
                $clone.find("[id]").each(function() {
                    var $this = $(this);
                    $this.attr("id", $this.attr("id") + "_clone")
                });
                return $clone
            },
            pauseInvisible: {
                visProp: null,
                init: function() {
                    var prefixes = ["webkit", "moz", "ms", "o"];
                    if ("hidden" in document) return "hidden";
                    for (var i = 0; i < prefixes.length; i++) {
                        if (prefixes[i] + "Hidden" in document) methods.pauseInvisible.visProp = prefixes[i] + "Hidden"
                    }
                    if (methods.pauseInvisible.visProp) {
                        var evtname = methods.pauseInvisible.visProp.replace(/[H|h]idden/, "") + "visibilitychange";
                        document.addEventListener(evtname,
                        function() {
                            if (methods.pauseInvisible.isHidden()) {
                                if (slider.startTimeout) clearTimeout(slider.startTimeout);
                                else slider.pause()
                            } else {
                                if (slider.started) slider.play();
                                else slider.vars.initDelay > 0 ? setTimeout(slider.play, slider.vars.initDelay) : slider.play()
                            }
                        })
                    }
                },
                isHidden: function() {
                    return document[methods.pauseInvisible.visProp] || false
                }
            },
            setToClearWatchedEvent: function() {
                clearTimeout(watchedEventClearTimer);
                watchedEventClearTimer = setTimeout(function() {
                    watchedEvent = ""
                },
                3e3)
            }
        };
        slider.flexAnimate = function(target, pause, override, withSync, fromNav) {
            if (!slider.vars.animationLoop && target !== slider.currentSlide) {
                slider.direction = target > slider.currentSlide ? "next": "prev"
            }
            if (asNav && slider.pagingCount === 1) slider.direction = slider.currentItem < target ? "next": "prev";
            if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) {
                if (asNav && withSync) {
                    var master = $(slider.vars.asNavFor).data("flexslider");
                    slider.atEnd = target === 0 || target === slider.count - 1;
                    master.flexAnimate(target, true, false, true, fromNav);
                    slider.direction = slider.currentItem < target ? "next": "prev";
                    master.direction = slider.direction;
                    if (Math.ceil((target + 1) / slider.visible) - 1 !== slider.currentSlide && target !== 0) {
                        slider.currentItem = target;
                        slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
                        target = Math.floor(target / slider.visible)
                    } else {
                        slider.currentItem = target;
                        slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
                        return false
                    }
                }
                slider.animating = true;
                slider.animatingTo = target;
                if (pause) slider.pause();
                slider.vars.before(slider);
                if (slider.syncExists && !fromNav) methods.sync("animate");
                if (slider.vars.controlNav) methods.controlNav.active();
                if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
                slider.atEnd = target === 0 || target === slider.last;
                if (slider.vars.directionNav) methods.directionNav.update();
                if (target === slider.last) {
                    slider.vars.end(slider);
                    if (!slider.vars.animationLoop) slider.pause()
                }
                if (!fade) {
                    var dimension = vertical ? slider.slides.filter(":first").height() : slider.computedW,
                    margin,
                    slideString,
                    calcNext;
                    if (carousel) {
                        margin = slider.vars.itemMargin;
                        calcNext = (slider.itemW + margin) * slider.move * slider.animatingTo;
                        slideString = calcNext > slider.limit && slider.visible !== 1 ? slider.limit: calcNext
                    } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") {
                        slideString = reverse ? (slider.count + slider.cloneOffset) * dimension: 0
                    } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") {
                        slideString = reverse ? 0 : (slider.count + 1) * dimension
                    } else {
                        slideString = reverse ? (slider.count - 1 - target + slider.cloneOffset) * dimension: (target + slider.cloneOffset) * dimension
                    }
                    slider.setProps(slideString, "", slider.vars.animationSpeed);
                    if (slider.transitions) {
                        if (!slider.vars.animationLoop || !slider.atEnd) {
                            slider.animating = false;
                            slider.currentSlide = slider.animatingTo
                        }
                        slider.container.unbind("webkitTransitionEnd transitionend");
                        slider.container.bind("webkitTransitionEnd transitionend",
                        function() {
                            slider.wrapup(dimension)
                        })
                    } else {
                        slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing,
                        function() {
                            slider.wrapup(dimension)
                        })
                    }
                } else {
                    if (!touch) {
                        slider.slides.eq(slider.currentSlide).css({
                            zIndex: 1
                        }).animate({
                            opacity: 0
                        },
                        slider.vars.animationSpeed, slider.vars.easing);
                        slider.slides.eq(target).css({
                            zIndex: 2
                        }).animate({
                            opacity: 1
                        },
                        slider.vars.animationSpeed, slider.vars.easing, slider.wrapup)
                    } else {
                        slider.slides.eq(slider.currentSlide).css({
                            opacity: 0,
                            zIndex: 1
                        });
                        slider.slides.eq(target).css({
                            opacity: 1,
                            zIndex: 2
                        });
                        slider.wrapup(dimension)
                    }
                }
                if (slider.vars.smoothHeight) methods.smoothHeight(slider.vars.animationSpeed)
            }
        };
        slider.wrapup = function(dimension) {
            if (!fade && !carousel) {
                if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) {
                    slider.setProps(dimension, "jumpEnd")
                } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) {
                    slider.setProps(dimension, "jumpStart")
                }
            }
            slider.animating = false;
            slider.currentSlide = slider.animatingTo;
            slider.vars.after(slider)
        };
        slider.animateSlides = function() {
            if (!slider.animating && focused) slider.flexAnimate(slider.getTarget("next"))
        };
        slider.pause = function() {
            clearInterval(slider.animatedSlides);
            slider.animatedSlides = null;
            slider.playing = false;
            if (slider.vars.pausePlay) methods.pausePlay.update("play");
            if (slider.syncExists) methods.sync("pause")
        };
        slider.play = function() {
            if (slider.playing) clearInterval(slider.animatedSlides);
            slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
            slider.started = slider.playing = true;
            if (slider.vars.pausePlay) methods.pausePlay.update("pause");
            if (slider.syncExists) methods.sync("play")
        };
        slider.stop = function() {
            slider.pause();
            slider.stopped = true
        };
        slider.canAdvance = function(target, fromNav) {
            var last = asNav ? slider.pagingCount - 1 : slider.last;
            return fromNav ? true: asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev" ? true: asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next" ? false: target === slider.currentSlide && !asNav ? false: slider.vars.animationLoop ? true: slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next" ? false: slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next" ? false: true
        };
        slider.getTarget = function(dir) {
            slider.direction = dir;
            if (dir === "next") {
                return slider.currentSlide === slider.last ? 0 : slider.currentSlide + 1
            } else {
                return slider.currentSlide === 0 ? slider.last: slider.currentSlide - 1
            }
        };
        slider.setProps = function(pos, special, dur) {
            var target = function() {
                var posCheck = pos ? pos: (slider.itemW + slider.vars.itemMargin) * slider.move * slider.animatingTo,
                posCalc = function() {
                    if (carousel) {
                        return special === "setTouch" ? pos: reverse && slider.animatingTo === slider.last ? 0 : reverse ? slider.limit - (slider.itemW + slider.vars.itemMargin) * slider.move * slider.animatingTo: slider.animatingTo === slider.last ? slider.limit: posCheck
                    } else {
                        switch (special) {
                        case "setTotal":
                            return reverse ? (slider.count - 1 - slider.currentSlide + slider.cloneOffset) * pos: (slider.currentSlide + slider.cloneOffset) * pos;
                        case "setTouch":
                            return reverse ? pos: pos;
                        case "jumpEnd":
                            return reverse ? pos: slider.count * pos;
                        case "jumpStart":
                            return reverse ? slider.count * pos: pos;
                        default:
                            return pos
                        }
                    }
                } ();
                return posCalc * -1 + "px"
            } ();
            if (slider.transitions) {
                target = vertical ? "translate3d(0," + target + ",0)": "translate3d(" + target + ",0,0)";
                dur = dur !== undefined ? dur / 1e3 + "s": "0s";
                slider.container.css("-" + slider.pfx + "-transition-duration", dur);
                slider.container.css("transition-duration", dur)
            }
            slider.args[slider.prop] = target;
            if (slider.transitions || dur === undefined) slider.container.css(slider.args);
            slider.container.css("transform", target)
        };
        slider.setup = function(type) {
            if (!fade) {
                var sliderOffset, arr;
                if (type === "init") {
                    slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({
                        overflow: "hidden",
                        position: "relative"
                    }).appendTo(slider).append(slider.container);
                    slider.cloneCount = 0;
                    slider.cloneOffset = 0;
                    if (reverse) {
                        arr = $.makeArray(slider.slides).reverse();
                        slider.slides = $(arr);
                        slider.container.empty().append(slider.slides)
                    }
                }
                if (slider.vars.animationLoop && !carousel) {
                    slider.cloneCount = 2;
                    slider.cloneOffset = 1;
                    if (type !== "init") slider.container.find(".clone").remove();
                    slider.container.append(slider.slides.first().clone().addClass("clone").attr("aria-hidden", "true")).prepend(slider.slides.last().clone().addClass("clone").attr("aria-hidden", "true"));
                    methods.uniqueID(slider.slides.first().clone().addClass("clone")).appendTo(slider.container);
                    methods.uniqueID(slider.slides.last().clone().addClass("clone")).prependTo(slider.container)
                }
                slider.newSlides = $(slider.vars.selector, slider);
                sliderOffset = reverse ? slider.count - 1 - slider.currentSlide + slider.cloneOffset: slider.currentSlide + slider.cloneOffset;
                if (vertical && !carousel) {
                    slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%");
                    setTimeout(function() {
                        slider.newSlides.css({
                            display: "block"
                        });
                        slider.doMath();
                        slider.viewport.height(slider.h);
                        slider.setProps(sliderOffset * slider.h, "init")
                    },
                    type === "init" ? 100 : 0)
                } else {
                    slider.container.width((slider.count + slider.cloneCount) * 200 + "%");
                    slider.setProps(sliderOffset * slider.computedW, "init");
                    setTimeout(function() {
                        slider.doMath();
                        slider.newSlides.css({
                            width: slider.computedW,
                            "float": "left",
                            display: "block"
                        });
                        if (slider.vars.smoothHeight) methods.smoothHeight()
                    },
                    type === "init" ? 100 : 0)
                }
            } else {
                slider.slides.css({
                    width: "100%",
                    "float": "left",
                    marginRight: "-100%",
                    position: "relative"
                });
                if (type === "init") {
                    if (!touch) {
                        slider.slides.css({
                            opacity: 0,
                            display: "block",
                            zIndex: 1
                        }).eq(slider.currentSlide).css({
                            zIndex: 2
                        }).animate({
                            opacity: 1
                        },
                        slider.vars.animationSpeed, slider.vars.easing)
                    } else {
                        slider.slides.css({
                            opacity: 0,
                            display: "block",
                            webkitTransition: "opacity " + slider.vars.animationSpeed / 1e3 + "s ease",
                            zIndex: 1
                        }).eq(slider.currentSlide).css({
                            opacity: 1,
                            zIndex: 2
                        })
                    }
                }
                if (slider.vars.smoothHeight) methods.smoothHeight()
            }
            if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide");
            slider.vars.init(slider)
        };
        slider.doMath = function() {
            var slide = slider.slides.first(),
            slideMargin = slider.vars.itemMargin,
            minItems = slider.vars.minItems,
            maxItems = slider.vars.maxItems;
            slider.w = slider.viewport === undefined ? slider.width() : slider.viewport.width();
            slider.h = slide.height();
            slider.boxPadding = slide.outerWidth() - slide.width();
            if (carousel) {
                slider.itemT = slider.vars.itemWidth + slideMargin;
                slider.minW = minItems ? minItems * slider.itemT: slider.w;
                slider.maxW = maxItems ? maxItems * slider.itemT - slideMargin: slider.w;
                slider.itemW = slider.minW > slider.w ? (slider.w - slideMargin * (minItems - 1)) / minItems: slider.maxW < slider.w ? (slider.w - slideMargin * (maxItems - 1)) / maxItems: slider.vars.itemWidth > slider.w ? slider.w: slider.vars.itemWidth;
                slider.visible = Math.floor(slider.w / slider.itemW);
                slider.move = slider.vars.move > 0 && slider.vars.move < slider.visible ? slider.vars.move: slider.visible;
                slider.pagingCount = Math.ceil((slider.count - slider.visible) / slider.move + 1);
                slider.last = slider.pagingCount - 1;
                slider.limit = slider.pagingCount === 1 ? 0 : slider.vars.itemWidth > slider.w ? slider.itemW * (slider.count - 1) + slideMargin * (slider.count - 1) : (slider.itemW + slideMargin) * slider.count - slider.w - slideMargin
            } else {
                slider.itemW = slider.w;
                slider.pagingCount = slider.count;
                slider.last = slider.count - 1
            }
            slider.computedW = slider.itemW - slider.boxPadding
        };
        slider.update = function(pos, action) {
            slider.doMath();
            if (!carousel) {
                if (pos < slider.currentSlide) {
                    slider.currentSlide += 1
                } else if (pos <= slider.currentSlide && pos !== 0) {
                    slider.currentSlide -= 1
                }
                slider.animatingTo = slider.currentSlide
            }
            if (slider.vars.controlNav && !slider.manualControls) {
                if (action === "add" && !carousel || slider.pagingCount > slider.controlNav.length) {
                    methods.controlNav.update("add")
                } else if (action === "remove" && !carousel || slider.pagingCount < slider.controlNav.length) {
                    if (carousel && slider.currentSlide > slider.last) {
                        slider.currentSlide -= 1;
                        slider.animatingTo -= 1
                    }
                    methods.controlNav.update("remove", slider.last)
                }
            }
            if (slider.vars.directionNav) methods.directionNav.update()
        };
        slider.addSlide = function(obj, pos) {
            var $obj = $(obj);
            slider.count += 1;
            slider.last = slider.count - 1;
            if (vertical && reverse) {
                pos !== undefined ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj)
            } else {
                pos !== undefined ? slider.slides.eq(pos).before($obj) : slider.container.append($obj)
            }
            slider.update(pos, "add");
            slider.slides = $(slider.vars.selector + ":not(.clone)", slider);
            slider.setup();
            slider.vars.added(slider)
        };
        slider.removeSlide = function(obj) {
            var pos = isNaN(obj) ? slider.slides.index($(obj)) : obj;
            slider.count -= 1;
            slider.last = slider.count - 1;
            if (isNaN(obj)) {
                $(obj, slider.slides).remove()
            } else {
                vertical && reverse ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove()
            }
            slider.doMath();
            slider.update(pos, "remove");
            slider.slides = $(slider.vars.selector + ":not(.clone)", slider);
            slider.setup();
            slider.vars.removed(slider)
        };
        methods.init()
    };
    $(window).blur(function(e) {
        focused = false
    }).focus(function(e) {
        focused = true
    });
    $.flexslider.defaults = {
        namespace: "flex-",
        selector: ".slides > li",
        animation: "fade",
        easing: "swing",
        direction: "horizontal",
        reverse: false,
        animationLoop: true,
        smoothHeight: false,
        startAt: 0,
        slideshow: true,
        slideshowSpeed: 7e3,
        animationSpeed: 600,
        initDelay: 0,
        randomize: false,
        thumbCaptions: false,
        pauseOnAction: true,
        pauseOnHover: false,
        pauseInvisible: true,
        useCSS: true,
        touch: true,
        video: false,
        controlNav: true,
        directionNav: true,
        prevText: "Previous",
        nextText: "Next",
        keyboard: true,
        multipleKeyboard: false,
        mousewheel: false,
        pausePlay: false,
        pauseText: "Pause",
        playText: "Play",
        controlsContainer: "",
        manualControls: "",
        sync: "",
        asNavFor: "",
        itemWidth: 0,
        itemMargin: 0,
        minItems: 1,
        maxItems: 0,
        move: 0,
        allowOneSlide: true,
        start: function() {},
        before: function() {},
        after: function() {},
        end: function() {},
        added: function() {},
        removed: function() {},
        init: function() {}
    };
    $.fn.flexslider = function(options) {
        if (options === undefined) options = {};
        if (typeof options === "object") {
            return this.each(function() {
                var $this = $(this),
                selector = options.selector ? options.selector: ".slides > li",
                $slides = $this.find(selector);
                if ($slides.length === 1 && options.allowOneSlide === true || $slides.length === 0) {
                    $slides.fadeIn(400);
                    if (options.start) options.start($this)
                } else if ($this.data("flexslider") === undefined) {
                    new $.flexslider(this, options)
                }
            })
        } else {
            var $slider = $(this).data("flexslider");
            switch (options) {
            case "play":
                $slider.play();
                break;
            case "pause":
                $slider.pause();
                break;
            case "stop":
                $slider.stop();
                break;
            case "next":
                $slider.flexAnimate($slider.getTarget("next"), true);
                break;
            case "prev":
            case "previous":
                $slider.flexAnimate($slider.getTarget("prev"), true);
                break;
            default:
                if (typeof options === "number") $slider.flexAnimate(options, true)
            }
        }
    }
})(jQuery);
var _st = window.setTimeout;
window.setTimeout = function(fRef, mDelay) {
    if (typeof fRef == "function") {
        var argu = Array.prototype.slice.call(arguments, 2);
        var f = function() {
            fRef.apply(null, argu)
        };
        return _st(f, mDelay)
    }
    return _st(fRef, mDelay)
};
$.fn.realVal = function() {
    var $obj = $(this);
    var type = $obj.attr("type");
    if (type && type === "checkbox") {
        var allVals = [];
        $obj.each(function() {
            if ($(this).is(":checked")) {
                allVals.push($(this).val())
            }
        });
        return allVals.length > 0 ? allVals: ""
    } else if (type && type === "radio") {
        var singleVal = "";
        $obj.each(function() {
            if ($(this).is(":checked")) {
                singleVal = $(this).val()
            }
        });
        return singleVal
    } else {
        return $obj.val()
    }
};
function validate(form, name, helper, type) {
    var isValid = false;
    var field = $('[name*="' + name + '"]');
    if (field == undefined || field.length <= 0) return isValid;
    var value = field.realVal();
    $.get(form.attr("action"), {
        name: name,
        value: value
    },
    function(data) {
        if (data.error) {
            console.log(name + " errored with " + data.message);
            return isValid
        }
        var icon = helper.find(".icon-form-check, .icon-form-error");
        if (icon.length <= 0) {
            icon = $("<div/>")
        }
        if (data.valid) {
            isValid = true;
            helper.html("").removeClass("error").addClass("valid");
            helper.prev(".form-widget").removeClass("error").addClass("valid");
            icon.prependTo(helper).removeClass("icon-form-error").removeClass("icon-form-check").addClass("icon-form-check")
        } else {
            helper.html(data.message).removeClass("valid").addClass("error");
            helper.prev(".form-widget").removeClass("valid").addClass("error");
            icon.prependTo(helper).removeClass("icon-form-error").removeClass("icon-form-check").addClass("icon-form-error")
        }
    });
    return isValid
}
$(document).ready(function() {
    $("input[data-mask]").each(function() {
        $(this).mask($(this).attr("data-mask"))
    });
    $("form").submit(function() {
        $(":submit", this).click(function() {
            return false
        })
    });
    $("form").each(function() {
        var form = $(this);
        if (form.attr("data-autocorrect") == undefined) return;
        validateFields = form.attr("data-autocorrect").split(",");
        selectors = "";
        for (var i = 0; i < validateFields.length; i++) {
            if (selectors.length > 0) selectors += ",";
            selectors += "[name*='" + validateFields[i] + "']"
        }
        form.find(selectors).each(function(el) {
            $(this).on("change blur",
            function() {
                validate(form, $(this).attr("name"), $(this).closest(".form-row").find(".helper"), $(this).prop("type"))
            })
        })
    })
}); (function() {
    var f = !1,
    i, k = this;
    function l(a, c) {
        var b = a.split("."),
        d = k; ! (b[0] in d) && d.execScript && d.execScript("var " + b[0]);
        for (var e; b.length && (e = b.shift());) ! b.length && void 0 !== c ? d[e] = c: d = d[e] ? d[e] : d[e] = {}
    }
    var m = Array.prototype,
    n = m.forEach ?
    function(a, c, b) {
        m.forEach.call(a, c, b)
    }: function(a, c, b) {
        for (var d = a.length,
        e = "string" == typeof a ? a.split("") : a, g = 0; g < d; g++) g in e && c.call(b, e[g], g, a)
    };
    function q(a, c) {
        this.c = {};
        this.a = [];
        var b = arguments.length;
        if (1 < b) {
            if (b % 2) throw Error("Uneven number of arguments");
            for (var d = 0; d < b; d += 2) this.set(arguments[d], arguments[d + 1])
        } else if (a) {
            var e;
            if (a instanceof q) {
                r(a);
                d = a.a.concat();
                r(a);
                e = [];
                for (b = 0; b < a.a.length; b++) e.push(a.c[a.a[b]])
            } else {
                var b = [],
                g = 0;
                for (d in a) b[g++] = d;
                d = b;
                b = [];
                g = 0;
                for (e in a) b[g++] = a[e];
                e = b
            }
            for (b = 0; b < d.length; b++) this.set(d[b], e[b])
        }
    }
    q.prototype.f = 0;
    q.prototype.p = 0;
    function r(a) {
        if (a.f != a.a.length) {
            for (var c = 0,
            b = 0; c < a.a.length;) {
                var d = a.a[c];
                t(a.c, d) && (a.a[b++] = d);
                c++
            }
            a.a.length = b
        }
        if (a.f != a.a.length) {
            for (var e = {},
            b = c = 0; c < a.a.length;) d = a.a[c],
            t(e, d) || (a.a[b++] = d, e[d] = 1),
            c++;
            a.a.length = b
        }
    }
    q.prototype.get = function(a, c) {
        return t(this.c, a) ? this.c[a] : c
    };
    q.prototype.set = function(a, c) {
        t(this.c, a) || (this.f++, this.a.push(a), this.p++);
        this.c[a] = c
    };
    function t(a, c) {
        return Object.prototype.hasOwnProperty.call(a, c)
    }
    var u, v, w, x;
    function y() {
        return k.navigator ? k.navigator.userAgent: null
    }
    x = w = v = u = f;
    var C;
    if (C = y()) {
        var D = k.navigator;
        u = 0 == C.indexOf("Opera");
        v = !u && -1 != C.indexOf("MSIE");
        w = !u && -1 != C.indexOf("WebKit");
        x = !u && !w && "Gecko" == D.product
    }
    var E = v,
    F = x,
    G = w;
    var I;
    if (u && k.opera) {
        var J = k.opera.version;
        "function" == typeof J && J()
    } else F ? I = /rv\:([^\);]+)(\)|;)/: E ? I = /MSIE\s+([^\);]+)(\)|;)/: G && (I = /WebKit\/(\S+)/),
    I && I.exec(y());
    function K(a, c) {
        this.b = a || {
            e: "",
            prefix: "",
            host: "",
            scheme: ""
        };
        this.h(c || {})
    }
    K.g = function() {
        return K.j ? K.j: K.j = new K
    };
    i = K.prototype;
    i.h = function(a) {
        this.d = new q(a)
    };
    i.o = function() {
        return this.d
    };
    i.k = function(a) {
        this.b.e = a
    };
    i.n = function() {
        return this.b.e
    };
    i.l = function(a) {
        this.b.prefix = a
    };
    function L(a, c, b, d) {
        var e, g = RegExp(/\[\]$/);
        if (b instanceof Array) n(b,
        function(b, e) {
            g.test(c) ? d(c, b) : L(a, c + "[" + ("object" === typeof b ? e: "") + "]", b, d)
        });
        else if ("object" === typeof b) for (e in b) L(a, c + "[" + e + "]", b[e], d);
        else d(c, b)
    }
    i.i = function(a) {
        var c = this.b.prefix + a;
        if (t(this.d.c, c)) a = c;
        else if (!t(this.d.c, a)) throw Error('The route "' + a + '" does not exist.');
        return this.d.get(a)
    };
    i.m = function(a, c, b) {
        var d = this.i(a),
        e = c || {},
        g = {},
        z;
        for (z in e) g[z] = e[z];
        var h = "",
        s = !0,
        j = "";
        n(d.tokens,
        function(b) {
            if ("text" === b[0]) h = b[1] + h,
            s = f;
            else if ("variable" === b[0]) {
                var c = b[3] in d.defaults;
                if (f === s || !c || b[3] in e && e[b[3]] != d.defaults[b[3]]) {
                    if (b[3] in e) {
                        var c = e[b[3]],
                        p = b[3];
                        p in g && delete g[p]
                    } else if (c) c = d.defaults[b[3]];
                    else {
                        if (s) return;
                        throw Error('The route "' + a + '" requires the parameter "' + b[3] + '".')
                    }
                    if (! (!0 === c || f === c || "" === c) || !s) p = encodeURIComponent(c).replace(/%2F/g, "/"),
                    "null" === p && null === c && (p = ""),
                    h = b[1] + p + h;
                    s = f
                } else c && (b = b[3], b in g && delete g[b])
            } else throw Error('The token type "' + b[0] + '" is not supported.')
        });
        "" === h && (h = "/");
        n(d.hosttokens,
        function(a) {
            var b;
            if ("text" === a[0]) j = a[1] + j;
            else if ("variable" === a[0]) {
                if (a[3] in e) {
                    b = e[a[3]];
                    var c = a[3];
                    c in g && delete g[c]
                } else a[3] in d.defaults && (b = d.defaults[a[3]]);
                j = a[1] + b + j
            }
        });
        h = this.b.e + h;
        "_scheme" in d.requirements && this.b.scheme != d.requirements._scheme ? h = d.requirements._scheme + "://" + (j || this.b.host) + h: j && this.b.host !== j ? h = this.b.scheme + "://" + j + h: !0 === b && (h = this.b.scheme + "://" + this.b.host + h);
        var c = 0,
        A;
        for (A in g) c++;
        if (0 < c) {
            var B, H = [];
            A = function(a, b) {
                b = "function" === typeof b ? b() : b;
                H.push(encodeURIComponent(a) + "=" + encodeURIComponent(null === b ? "": b))
            };
            for (B in g) L(this, B, g[B], A);
            h = h + "?" + H.join("&").replace(/%20/g, "+")
        }
        return h
    };
    l("fos.Router", K);
    l("fos.Router.setData",
    function(a) {
        var c = K.g();
        c.k(a.base_url);
        c.h(a.routes);
        "prefix" in a && c.l(a.prefix);
        c.b.host = a.host;
        c.b.scheme = a.scheme
    });
    K.getInstance = K.g;
    K.prototype.setRoutes = K.prototype.h;
    K.prototype.getRoutes = K.prototype.o;
    K.prototype.setBaseUrl = K.prototype.k;
    K.prototype.getBaseUrl = K.prototype.n;
    K.prototype.generate = K.prototype.m;
    K.prototype.setPrefix = K.prototype.l;
    K.prototype.getRoute = K.prototype.i;
    window.Routing = K.g()
})(); (function(factory) {
    if (typeof define === "function" && define.amd) {
        define(factory)
    } else {
        window.purl = factory()
    }
})(function() {
    var tag2attr = {
        a: "href",
        img: "src",
        form: "action",
        base: "href",
        script: "src",
        iframe: "src",
        link: "href"
    },
    key = ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "fragment"],
    aliases = {
        anchor: "fragment"
    },
    parser = {
        strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
        loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
    },
    isint = /^[0-9]+$/;
    function parseUri(url, strictMode) {
        var str = decodeURI(url),
        res = parser[strictMode || false ? "strict": "loose"].exec(str),
        uri = {
            attr: {},
            param: {},
            seg: {}
        },
        i = 14;
        while (i--) {
            uri.attr[key[i]] = res[i] || ""
        }
        uri.param["query"] = parseString(uri.attr["query"]);
        uri.param["fragment"] = parseString(uri.attr["fragment"]);
        uri.seg["path"] = uri.attr.path.replace(/^\/+|\/+$/g, "").split("/");
        uri.seg["fragment"] = uri.attr.fragment.replace(/^\/+|\/+$/g, "").split("/");
        uri.attr["base"] = uri.attr.host ? (uri.attr.protocol ? uri.attr.protocol + "://" + uri.attr.host: uri.attr.host) + (uri.attr.port ? ":" + uri.attr.port: "") : "";
        return uri
    }
    function getAttrName(elm) {
        var tn = elm.tagName;
        if (typeof tn !== "undefined") return tag2attr[tn.toLowerCase()];
        return tn
    }
    function promote(parent, key) {
        if (parent[key].length === 0) return parent[key] = {};
        var t = {};
        for (var i in parent[key]) t[i] = parent[key][i];
        parent[key] = t;
        return t
    }
    function parse(parts, parent, key, val) {
        var part = parts.shift();
        if (!part) {
            if (isArray(parent[key])) {
                parent[key].push(val)
            } else if ("object" == typeof parent[key]) {
                parent[key] = val
            } else if ("undefined" == typeof parent[key]) {
                parent[key] = val
            } else {
                parent[key] = [parent[key], val]
            }
        } else {
            var obj = parent[key] = parent[key] || [];
            if ("]" == part) {
                if (isArray(obj)) {
                    if ("" !== val) obj.push(val)
                } else if ("object" == typeof obj) {
                    obj[keys(obj).length] = val
                } else {
                    obj = parent[key] = [parent[key], val]
                }
            } else if (~part.indexOf("]")) {
                part = part.substr(0, part.length - 1);
                if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
                parse(parts, obj, part, val)
            } else {
                if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
                parse(parts, obj, part, val)
            }
        }
    }
    function merge(parent, key, val) {
        if (~key.indexOf("]")) {
            var parts = key.split("[");
            parse(parts, parent, "base", val)
        } else {
            if (!isint.test(key) && isArray(parent.base)) {
                var t = {};
                for (var k in parent.base) t[k] = parent.base[k];
                parent.base = t
            }
            if (key !== "") {
                set(parent.base, key, val)
            }
        }
        return parent
    }
    function parseString(str) {
        return reduce(String(str).split(/&|;/),
        function(ret, pair) {
            try {
                pair = decodeURIComponent(pair.replace(/\+/g, " "))
            } catch(e) {}
            var eql = pair.indexOf("="),
            brace = lastBraceInKey(pair),
            key = pair.substr(0, brace || eql),
            val = pair.substr(brace || eql, pair.length);
            val = val.substr(val.indexOf("=") + 1, val.length);
            if (key === "") {
                key = pair;
                val = ""
            }
            return merge(ret, key, val)
        },
        {
            base: {}
        }).base
    }
    function set(obj, key, val) {
        var v = obj[key];
        if (typeof v === "undefined") {
            obj[key] = val
        } else if (isArray(v)) {
            v.push(val)
        } else {
            obj[key] = [v, val]
        }
    }
    function lastBraceInKey(str) {
        var len = str.length,
        brace, c;
        for (var i = 0; i < len; ++i) {
            c = str[i];
            if ("]" == c) brace = false;
            if ("[" == c) brace = true;
            if ("=" == c && !brace) return i
        }
    }
    function reduce(obj, accumulator) {
        var i = 0,
        l = obj.length >> 0,
        curr = arguments[2];
        while (i < l) {
            if (i in obj) curr = accumulator.call(undefined, curr, obj[i], i, obj); ++i
        }
        return curr
    }
    function isArray(vArg) {
        return Object.prototype.toString.call(vArg) === "[object Array]"
    }
    function keys(obj) {
        var key_array = [];
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) key_array.push(prop)
        }
        return key_array
    }
    function purl(url, strictMode) {
        if (arguments.length === 1 && url === true) {
            strictMode = true;
            url = undefined
        }
        strictMode = strictMode || false;
        url = url || window.location.toString();
        return {
            data: parseUri(url, strictMode),
            attr: function(attr) {
                attr = aliases[attr] || attr;
                return typeof attr !== "undefined" ? this.data.attr[attr] : this.data.attr
            },
            param: function(param) {
                return typeof param !== "undefined" ? this.data.param.query[param] : this.data.param.query
            },
            fparam: function(param) {
                return typeof param !== "undefined" ? this.data.param.fragment[param] : this.data.param.fragment
            },
            segment: function(seg) {
                if (typeof seg === "undefined") {
                    return this.data.seg.path
                } else {
                    seg = seg < 0 ? this.data.seg.path.length + seg: seg - 1;
                    return this.data.seg.path[seg]
                }
            },
            fsegment: function(seg) {
                if (typeof seg === "undefined") {
                    return this.data.seg.fragment
                } else {
                    seg = seg < 0 ? this.data.seg.fragment.length + seg: seg - 1;
                    return this.data.seg.fragment[seg]
                }
            }
        }
    }
    purl.jQuery = function($) {
        if ($ != null) {
            $.fn.url = function(strictMode) {
                var url = "";
                if (this.length) {
                    url = $(this).attr(getAttrName(this[0])) || ""
                }
                return purl(url, strictMode)
            };
            $.url = purl
        }
    };
    purl.jQuery(window.jQuery);
    return purl
}); (function() {
    function require(path, parent, orig) {
        var resolved = require.resolve(path);
        if (null == resolved) {
            orig = orig || path;
            parent = parent || "root";
            var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
            err.path = orig;
            err.parent = parent;
            err.require = true;
            throw err
        }
        var module = require.modules[resolved];
        if (!module._resolving && !module.exports) {
            var mod = {};
            mod.exports = {};
            mod.client = mod.component = true;
            module._resolving = true;
            module.call(this, mod.exports, require.relative(resolved), mod);
            delete module._resolving;
            module.exports = mod.exports
        }
        return module.exports
    }
    require.modules = {};
    require.aliases = {};
    require.resolve = function(path) {
        if (path.charAt(0) === "/") path = path.slice(1);
        var paths = [path, path + ".js", path + ".json", path + "/index.js", path + "/index.json"];
        for (var i = 0; i < paths.length; i++) {
            var path = paths[i];
            if (require.modules.hasOwnProperty(path)) return path;
            if (require.aliases.hasOwnProperty(path)) return require.aliases[path]
        }
    };
    require.normalize = function(curr, path) {
        var segs = [];
        if ("." != path.charAt(0)) return path;
        curr = curr.split("/");
        path = path.split("/");
        for (var i = 0; i < path.length; ++i) {
            if (".." == path[i]) {
                curr.pop()
            } else if ("." != path[i] && "" != path[i]) {
                segs.push(path[i])
            }
        }
        return curr.concat(segs).join("/")
    };
    require.register = function(path, definition) {
        require.modules[path] = definition
    };
    require.alias = function(from, to) {
        if (!require.modules.hasOwnProperty(from)) {
            throw new Error('Failed to alias "' + from + '", it does not exist')
        }
        require.aliases[to] = from
    };
    require.relative = function(parent) {
        var p = require.normalize(parent, "..");
        function lastIndexOf(arr, obj) {
            var i = arr.length;
            while (i--) {
                if (arr[i] === obj) return i
            }
            return - 1
        }
        function localRequire(path) {
            var resolved = localRequire.resolve(path);
            return require(resolved, parent, path)
        }
        localRequire.resolve = function(path) {
            var c = path.charAt(0);
            if ("/" == c) return path.slice(1);
            if ("." == c) return require.normalize(p, path);
            var segs = parent.split("/");
            var i = lastIndexOf(segs, "deps") + 1;
            if (!i) i = 0;
            path = segs.slice(0, i + 1).join("/") + "/deps/" + path;
            return path
        };
        localRequire.exists = function(path) {
            return require.modules.hasOwnProperty(localRequire.resolve(path))
        };
        return localRequire
    };
    require.register("component-emitter/index.js",
    function(exports, require, module) {
        module.exports = Emitter;
        function Emitter(obj) {
            if (obj) return mixin(obj)
        }
        function mixin(obj) {
            for (var key in Emitter.prototype) {
                obj[key] = Emitter.prototype[key]
            }
            return obj
        }
        Emitter.prototype.on = function(event, fn) {
            this._callbacks = this._callbacks || {}; (this._callbacks[event] = this._callbacks[event] || []).push(fn);
            return this
        };
        Emitter.prototype.once = function(event, fn) {
            var self = this;
            this._callbacks = this._callbacks || {};
            function on() {
                self.off(event, on);
                fn.apply(this, arguments)
            }
            fn._off = on;
            this.on(event, on);
            return this
        };
        Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = function(event, fn) {
            this._callbacks = this._callbacks || {};
            var callbacks = this._callbacks[event];
            if (!callbacks) return this;
            if (1 == arguments.length) {
                delete this._callbacks[event];
                return this
            }
            var i = callbacks.indexOf(fn._off || fn);
            if (~i) callbacks.splice(i, 1);
            return this
        };
        Emitter.prototype.emit = function(event) {
            this._callbacks = this._callbacks || {};
            var args = [].slice.call(arguments, 1),
            callbacks = this._callbacks[event];
            if (callbacks) {
                callbacks = callbacks.slice(0);
                for (var i = 0,
                len = callbacks.length; i < len; ++i) {
                    callbacks[i].apply(this, args)
                }
            }
            return this
        };
        Emitter.prototype.listeners = function(event) {
            this._callbacks = this._callbacks || {};
            return this._callbacks[event] || []
        };
        Emitter.prototype.hasListeners = function(event) {
            return !! this.listeners(event).length
        }
    });
    require.register("dropzone/index.js",
    function(exports, require, module) {
        module.exports = require("./lib/dropzone.js")
    });
    require.register("dropzone/lib/dropzone.js",
    function(exports, require, module) { (function() {
            var Dropzone, Em, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without, __hasProp = {}.hasOwnProperty,
            __extends = function(child, parent) {
                for (var key in parent) {
                    if (__hasProp.call(parent, key)) child[key] = parent[key]
                }
                function ctor() {
                    this.constructor = child
                }
                ctor.prototype = parent.prototype;
                child.prototype = new ctor;
                child.__super__ = parent.prototype;
                return child
            },
            __slice = [].slice;
            Em = typeof Emitter !== "undefined" && Emitter !== null ? Emitter: require("emitter");
            noop = function() {};
            Dropzone = function(_super) {
                var extend;
                __extends(Dropzone, _super);
                Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached"];
                Dropzone.prototype.defaultOptions = {
                    url: null,
                    method: "post",
                    withCredentials: false,
                    parallelUploads: 2,
                    uploadMultiple: false,
                    maxFilesize: 256,
                    paramName: "file",
                    createImageThumbnails: true,
                    maxThumbnailFilesize: 10,
                    thumbnailWidth: 100,
                    thumbnailHeight: 100,
                    maxFiles: null,
                    params: {},
                    clickable: true,
                    ignoreHiddenFiles: true,
                    acceptedFiles: null,
                    acceptedMimeTypes: null,
                    autoProcessQueue: true,
                    addRemoveLinks: false,
                    previewsContainer: null,
                    dictDefaultMessage: "Drop files here to upload",
                    dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
                    dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",
                    dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
                    dictInvalidFileType: "You can't upload files of this type.",
                    dictResponseError: "Server responded with {{statusCode}} code.",
                    dictCancelUpload: "Cancel upload",
                    dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
                    dictRemoveFile: "Remove file",
                    dictRemoveFileConfirmation: null,
                    dictMaxFilesExceeded: "You can not upload any more files.",
                    accept: function(file, done) {
                        return done()
                    },
                    init: function() {
                        return noop
                    },
                    forceFallback: false,
                    fallback: function() {
                        var child, messageElement, span, _i, _len, _ref;
                        this.element.className = "" + this.element.className + " dz-browser-not-supported";
                        _ref = this.element.getElementsByTagName("div");
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            child = _ref[_i];
                            if (/(^| )dz-message($| )/.test(child.className)) {
                                messageElement = child;
                                child.className = "dz-message";
                                continue
                            }
                        }
                        if (!messageElement) {
                            messageElement = Dropzone.createElement('<div class="dz-message"><span></span></div>');
                            this.element.appendChild(messageElement)
                        }
                        span = messageElement.getElementsByTagName("span")[0];
                        if (span) {
                            span.textContent = this.options.dictFallbackMessage
                        }
                        return this.element.appendChild(this.getFallbackForm())
                    },
                    resize: function(file) {
                        var info, srcRatio, trgRatio;
                        info = {
                            srcX: 0,
                            srcY: 0,
                            srcWidth: file.width,
                            srcHeight: file.height
                        };
                        srcRatio = file.width / file.height;
                        trgRatio = this.options.thumbnailWidth / this.options.thumbnailHeight;
                        if (file.height < this.options.thumbnailHeight || file.width < this.options.thumbnailWidth) {
                            info.trgHeight = info.srcHeight;
                            info.trgWidth = info.srcWidth
                        } else {
                            if (srcRatio > trgRatio) {
                                info.srcHeight = file.height;
                                info.srcWidth = info.srcHeight * trgRatio
                            } else {
                                info.srcWidth = file.width;
                                info.srcHeight = info.srcWidth / trgRatio
                            }
                        }
                        info.srcX = (file.width - info.srcWidth) / 2;
                        info.srcY = (file.height - info.srcHeight) / 2;
                        return info
                    },
                    drop: function(e) {
                        return this.element.classList.remove("dz-drag-hover")
                    },
                    dragstart: noop,
                    dragend: function(e) {
                        return this.element.classList.remove("dz-drag-hover")
                    },
                    dragenter: function(e) {
                        return this.element.classList.add("dz-drag-hover")
                    },
                    dragover: function(e) {
                        return this.element.classList.add("dz-drag-hover")
                    },
                    dragleave: function(e) {
                        return this.element.classList.remove("dz-drag-hover")
                    },
                    paste: noop,
                    reset: function() {
                        return this.element.classList.remove("dz-started")
                    },
                    addedfile: function(file) {
                        var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results, _this = this;
                        if (this.element === this.previewsContainer) {
                            this.element.classList.add("dz-started")
                        }
                        file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
                        file.previewTemplate = file.previewElement;
                        this.previewsContainer.appendChild(file.previewElement);
                        _ref = file.previewElement.querySelectorAll("[data-dz-name]");
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            node = _ref[_i];
                            node.textContent = file.name
                        }
                        _ref1 = file.previewElement.querySelectorAll("[data-dz-size]");
                        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
                            node = _ref1[_j];
                            node.innerHTML = this.filesize(file.size)
                        }
                        if (this.options.addRemoveLinks) {
                            file._removeLink = Dropzone.createElement('<a class="dz-remove" href="javascript:undefined;" data-dz-remove>' + this.options.dictRemoveFile + "</a>");
                            file.previewElement.appendChild(file._removeLink)
                        }
                        removeFileEvent = function(e) {
                            e.preventDefault();
                            e.stopPropagation();
                            if (file.status === Dropzone.UPLOADING) {
                                return Dropzone.confirm(_this.options.dictCancelUploadConfirmation,
                                function() {
                                    return _this.removeFile(file)
                                })
                            } else {
                                if (_this.options.dictRemoveFileConfirmation) {
                                    return Dropzone.confirm(_this.options.dictRemoveFileConfirmation,
                                    function() {
                                        return _this.removeFile(file)
                                    })
                                } else {
                                    return _this.removeFile(file)
                                }
                            }
                        };
                        _ref2 = file.previewElement.querySelectorAll("[data-dz-remove]");
                        _results = [];
                        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
                            removeLink = _ref2[_k];
                            _results.push(removeLink.addEventListener("click", removeFileEvent))
                        }
                        return _results
                    },
                    removedfile: function(file) {
                        var _ref;
                        if ((_ref = file.previewElement) != null) {
                            _ref.parentNode.removeChild(file.previewElement)
                        }
                        return this._updateMaxFilesReachedClass()
                    },
                    thumbnail: function(file, dataUrl) {
                        var thumbnailElement, _i, _len, _ref, _results;
                        file.previewElement.classList.remove("dz-file-preview");
                        file.previewElement.classList.add("dz-image-preview");
                        _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
                        _results = [];
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            thumbnailElement = _ref[_i];
                            thumbnailElement.alt = file.name;
                            _results.push(thumbnailElement.src = dataUrl)
                        }
                        return _results
                    },
                    error: function(file, message) {
                        var node, _i, _len, _ref, _results;
                        file.previewElement.classList.add("dz-error");
                        if (typeof message !== "String" && message.error) {
                            message = message.error
                        }
                        _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
                        _results = [];
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            node = _ref[_i];
                            _results.push(node.textContent = message)
                        }
                        return _results
                    },
                    errormultiple: noop,
                    processing: function(file) {
                        file.previewElement.classList.add("dz-processing");
                        if (file._removeLink) {
                            return file._removeLink.textContent = this.options.dictCancelUpload
                        }
                    },
                    processingmultiple: noop,
                    uploadprogress: function(file, progress, bytesSent) {
                        var node, _i, _len, _ref, _results;
                        _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]");
                        _results = [];
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            node = _ref[_i];
                            _results.push(node.style.width = "" + progress + "%")
                        }
                        return _results
                    },
                    totaluploadprogress: noop,
                    sending: noop,
                    sendingmultiple: noop,
                    success: function(file) {
                        return file.previewElement.classList.add("dz-success")
                    },
                    successmultiple: noop,
                    canceled: function(file) {
                        return this.emit("error", file, "Upload canceled.")
                    },
                    canceledmultiple: noop,
                    complete: function(file) {
                        if (file._removeLink) {
                            return file._removeLink.textContent = this.options.dictRemoveFile
                        }
                    },
                    completemultiple: noop,
                    maxfilesexceeded: noop,
                    maxfilesreached: noop,
                    previewTemplate: '<div class="dz-preview dz-file-preview">\n  <div class="dz-details">\n    <div class="dz-filename"><span data-dz-name></span></div>\n    <div class="dz-size" data-dz-size></div>\n    <img data-dz-thumbnail />\n  </div>\n  <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>\n  <div class="dz-success-mark"><span>✔</span></div>\n  <div class="dz-error-mark"><span>✘</span></div>\n  <div class="dz-error-message"><span data-dz-errormessage></span></div>\n</div>'
                };
                extend = function() {
                    var key, object, objects, target, val, _i, _len;
                    target = arguments[0],
                    objects = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
                    for (_i = 0, _len = objects.length; _i < _len; _i++) {
                        object = objects[_i];
                        for (key in object) {
                            val = object[key];
                            target[key] = val
                        }
                    }
                    return target
                };
                function Dropzone(element, options) {
                    var elementOptions, fallback, _ref;
                    this.element = element;
                    this.version = Dropzone.version;
                    this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
                    this.clickableElements = [];
                    this.listeners = [];
                    this.files = [];
                    if (typeof this.element === "string") {
                        this.element = document.querySelector(this.element)
                    }
                    if (! (this.element && this.element.nodeType != null)) {
                        throw new Error("Invalid dropzone element.")
                    }
                    if (this.element.dropzone) {
                        throw new Error("Dropzone already attached.")
                    }
                    Dropzone.instances.push(this);
                    this.element.dropzone = this;
                    elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref: {};
                    this.options = extend({},
                    this.defaultOptions, elementOptions, options != null ? options: {});
                    if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {
                        return this.options.fallback.call(this)
                    }
                    if (this.options.url == null) {
                        this.options.url = this.element.getAttribute("action")
                    }
                    if (!this.options.url) {
                        throw new Error("No URL provided.")
                    }
                    if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {
                        throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.")
                    }
                    if (this.options.acceptedMimeTypes) {
                        this.options.acceptedFiles = this.options.acceptedMimeTypes;
                        delete this.options.acceptedMimeTypes
                    }
                    this.options.method = this.options.method.toUpperCase();
                    if ((fallback = this.getExistingFallback()) && fallback.parentNode) {
                        fallback.parentNode.removeChild(fallback)
                    }
                    if (this.options.previewsContainer) {
                        this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer")
                    } else {
                        this.previewsContainer = this.element
                    }
                    if (this.options.clickable) {
                        if (this.options.clickable === true) {
                            this.clickableElements = [this.element]
                        } else {
                            this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable")
                        }
                    }
                    this.init()
                }
                Dropzone.prototype.getAcceptedFiles = function() {
                    var file, _i, _len, _ref, _results;
                    _ref = this.files;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        file = _ref[_i];
                        if (file.accepted) {
                            _results.push(file)
                        }
                    }
                    return _results
                };
                Dropzone.prototype.getRejectedFiles = function() {
                    var file, _i, _len, _ref, _results;
                    _ref = this.files;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        file = _ref[_i];
                        if (!file.accepted) {
                            _results.push(file)
                        }
                    }
                    return _results
                };
                Dropzone.prototype.getQueuedFiles = function() {
                    var file, _i, _len, _ref, _results;
                    _ref = this.files;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        file = _ref[_i];
                        if (file.status === Dropzone.QUEUED) {
                            _results.push(file)
                        }
                    }
                    return _results
                };
                Dropzone.prototype.getUploadingFiles = function() {
                    var file, _i, _len, _ref, _results;
                    _ref = this.files;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        file = _ref[_i];
                        if (file.status === Dropzone.UPLOADING) {
                            _results.push(file)
                        }
                    }
                    return _results
                };
                Dropzone.prototype.init = function() {
                    var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1, _this = this;
                    if (this.element.tagName === "form") {
                        this.element.setAttribute("enctype", "multipart/form-data")
                    }
                    if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
                        this.element.appendChild(Dropzone.createElement('<div class="dz-default dz-message"><span>' + this.options.dictDefaultMessage + "</span></div>"))
                    }
                    if (this.clickableElements.length) {
                        setupHiddenFileInput = function() {
                            if (_this.hiddenFileInput) {
                                document.body.removeChild(_this.hiddenFileInput)
                            }
                            _this.hiddenFileInput = document.createElement("input");
                            _this.hiddenFileInput.setAttribute("type", "file");
                            if (_this.options.maxFiles == null || _this.options.maxFiles > 1) {
                                _this.hiddenFileInput.setAttribute("multiple", "multiple")
                            }
                            if (_this.options.acceptedFiles != null) {
                                _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles)
                            }
                            _this.hiddenFileInput.style.visibility = "hidden";
                            _this.hiddenFileInput.style.position = "absolute";
                            _this.hiddenFileInput.style.top = "0";
                            _this.hiddenFileInput.style.left = "0";
                            _this.hiddenFileInput.style.height = "0";
                            _this.hiddenFileInput.style.width = "0";
                            document.body.appendChild(_this.hiddenFileInput);
                            return _this.hiddenFileInput.addEventListener("change",
                            function() {
                                var file, files, _i, _len;
                                files = _this.hiddenFileInput.files;
                                if (files.length) {
                                    for (_i = 0, _len = files.length; _i < _len; _i++) {
                                        file = files[_i];
                                        _this.addFile(file)
                                    }
                                }
                                return setupHiddenFileInput()
                            })
                        };
                        setupHiddenFileInput()
                    }
                    this.URL = (_ref = window.URL) != null ? _ref: window.webkitURL;
                    _ref1 = this.events;
                    for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
                        eventName = _ref1[_i];
                        this.on(eventName, this.options[eventName])
                    }
                    this.on("uploadprogress",
                    function() {
                        return _this.updateTotalUploadProgress()
                    });
                    this.on("removedfile",
                    function() {
                        return _this.updateTotalUploadProgress()
                    });
                    this.on("canceled",
                    function(file) {
                        return _this.emit("complete", file)
                    });
                    this.on("complete",
                    function(file) {
                        if (_this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) {
                            return setTimeout(function() {
                                return _this.emit("queuecomplete")
                            },
                            0)
                        }
                    });
                    noPropagation = function(e) {
                        e.stopPropagation();
                        if (e.preventDefault) {
                            return e.preventDefault()
                        } else {
                            return e.returnValue = false
                        }
                    };
                    this.listeners = [{
                        element: this.element,
                        events: {
                            dragstart: function(e) {
                                return _this.emit("dragstart", e)
                            },
                            dragenter: function(e) {
                                noPropagation(e);
                                return _this.emit("dragenter", e)
                            },
                            dragover: function(e) {
                                var efct;
                                try {
                                    efct = e.dataTransfer.effectAllowed
                                } catch(_error) {}
                                e.dataTransfer.dropEffect = "move" === efct || "linkMove" === efct ? "move": "copy";
                                noPropagation(e);
                                return _this.emit("dragover", e)
                            },
                            dragleave: function(e) {
                                return _this.emit("dragleave", e)
                            },
                            drop: function(e) {
                                noPropagation(e);
                                return _this.drop(e)
                            },
                            dragend: function(e) {
                                return _this.emit("dragend", e)
                            }
                        }
                    }];
                    this.clickableElements.forEach(function(clickableElement) {
                        return _this.listeners.push({
                            element: clickableElement,
                            events: {
                                click: function(evt) {
                                    if (clickableElement !== _this.element || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) {
                                        return _this.hiddenFileInput.click()
                                    }
                                }
                            }
                        })
                    });
                    this.enable();
                    return this.options.init.call(this)
                };
                Dropzone.prototype.destroy = function() {
                    var _ref;
                    this.disable();
                    this.removeAllFiles(true);
                    if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode: void 0) {
                        this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
                        this.hiddenFileInput = null
                    }
                    delete this.element.dropzone;
                    return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1)
                };
                Dropzone.prototype.updateTotalUploadProgress = function() {
                    var acceptedFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref;
                    totalBytesSent = 0;
                    totalBytes = 0;
                    acceptedFiles = this.getAcceptedFiles();
                    if (acceptedFiles.length) {
                        _ref = this.getAcceptedFiles();
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            file = _ref[_i];
                            totalBytesSent += file.upload.bytesSent;
                            totalBytes += file.upload.total
                        }
                        totalUploadProgress = 100 * totalBytesSent / totalBytes
                    } else {
                        totalUploadProgress = 100
                    }
                    return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent)
                };
                Dropzone.prototype.getFallbackForm = function() {
                    var existingFallback, fields, fieldsString, form;
                    if (existingFallback = this.getExistingFallback()) {
                        return existingFallback
                    }
                    fieldsString = '<div class="dz-fallback">';
                    if (this.options.dictFallbackText) {
                        fieldsString += "<p>" + this.options.dictFallbackText + "</p>"
                    }
                    fieldsString += '<input type="file" name="' + this.options.paramName + (this.options.uploadMultiple ? "[]": "") + '" ' + (this.options.uploadMultiple ? 'multiple="multiple"': void 0) + ' /><input type="submit" value="Upload!"></div>';
                    fields = Dropzone.createElement(fieldsString);
                    if (this.element.tagName !== "FORM") {
                        form = Dropzone.createElement('<form action="' + this.options.url + '" enctype="multipart/form-data" method="' + this.options.method + '"></form>');
                        form.appendChild(fields)
                    } else {
                        this.element.setAttribute("enctype", "multipart/form-data");
                        this.element.setAttribute("method", this.options.method)
                    }
                    return form != null ? form: fields
                };
                Dropzone.prototype.getExistingFallback = function() {
                    var fallback, getFallback, tagName, _i, _len, _ref;
                    getFallback = function(elements) {
                        var el, _i, _len;
                        for (_i = 0, _len = elements.length; _i < _len; _i++) {
                            el = elements[_i];
                            if (/(^| )fallback($| )/.test(el.className)) {
                                return el
                            }
                        }
                    };
                    _ref = ["div", "form"];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        tagName = _ref[_i];
                        if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
                            return fallback
                        }
                    }
                };
                Dropzone.prototype.setupEventListeners = function() {
                    var elementListeners, event, listener, _i, _len, _ref, _results;
                    _ref = this.listeners;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        elementListeners = _ref[_i];
                        _results.push(function() {
                            var _ref1, _results1;
                            _ref1 = elementListeners.events;
                            _results1 = [];
                            for (event in _ref1) {
                                listener = _ref1[event];
                                _results1.push(elementListeners.element.addEventListener(event, listener, false))
                            }
                            return _results1
                        } ())
                    }
                    return _results
                };
                Dropzone.prototype.removeEventListeners = function() {
                    var elementListeners, event, listener, _i, _len, _ref, _results;
                    _ref = this.listeners;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        elementListeners = _ref[_i];
                        _results.push(function() {
                            var _ref1, _results1;
                            _ref1 = elementListeners.events;
                            _results1 = [];
                            for (event in _ref1) {
                                listener = _ref1[event];
                                _results1.push(elementListeners.element.removeEventListener(event, listener, false))
                            }
                            return _results1
                        } ())
                    }
                    return _results
                };
                Dropzone.prototype.disable = function() {
                    var file, _i, _len, _ref, _results;
                    this.clickableElements.forEach(function(element) {
                        return element.classList.remove("dz-clickable")
                    });
                    this.removeEventListeners();
                    _ref = this.files;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        file = _ref[_i];
                        _results.push(this.cancelUpload(file))
                    }
                    return _results
                };
                Dropzone.prototype.enable = function() {
                    this.clickableElements.forEach(function(element) {
                        return element.classList.add("dz-clickable")
                    });
                    return this.setupEventListeners()
                };
                Dropzone.prototype.filesize = function(size) {
                    var string;
                    if (size >= 1024 * 1024 * 1024 * 1024 / 10) {
                        size = size / (1024 * 1024 * 1024 * 1024 / 10);
                        string = "TiB"
                    } else if (size >= 1024 * 1024 * 1024 / 10) {
                        size = size / (1024 * 1024 * 1024 / 10);
                        string = "GiB"
                    } else if (size >= 1024 * 1024 / 10) {
                        size = size / (1024 * 1024 / 10);
                        string = "MiB"
                    } else if (size >= 1024 / 10) {
                        size = size / (1024 / 10);
                        string = "KiB"
                    } else {
                        size = size * 10;
                        string = "b"
                    }
                    return "<strong>" + Math.round(size) / 10 + "</strong> " + string
                };
                Dropzone.prototype._updateMaxFilesReachedClass = function() {
                    if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {
                        if (this.getAcceptedFiles().length === this.options.maxFiles) {
                            this.emit("maxfilesreached", this.files)
                        }
                        return this.element.classList.add("dz-max-files-reached")
                    } else {
                        return this.element.classList.remove("dz-max-files-reached")
                    }
                };
                Dropzone.prototype.drop = function(e) {
                    var files, items;
                    if (!e.dataTransfer) {
                        return
                    }
                    this.emit("drop", e);
                    files = e.dataTransfer.files;
                    if (files.length) {
                        items = e.dataTransfer.items;
                        if (items && items.length && items[0].webkitGetAsEntry != null) {
                            this._addFilesFromItems(items)
                        } else {
                            this.handleFiles(files)
                        }
                    }
                };
                Dropzone.prototype.paste = function(e) {
                    var items, _ref;
                    if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items: void 0 : void 0) == null) {
                        return
                    }
                    this.emit("paste", e);
                    items = e.clipboardData.items;
                    if (items.length) {
                        return this._addFilesFromItems(items)
                    }
                };
                Dropzone.prototype.handleFiles = function(files) {
                    var file, _i, _len, _results;
                    _results = [];
                    for (_i = 0, _len = files.length; _i < _len; _i++) {
                        file = files[_i];
                        _results.push(this.addFile(file))
                    }
                    return _results
                };
                Dropzone.prototype._addFilesFromItems = function(items) {
                    var entry, item, _i, _len, _results;
                    _results = [];
                    for (_i = 0, _len = items.length; _i < _len; _i++) {
                        item = items[_i];
                        if (item.webkitGetAsEntry != null && (entry = item.webkitGetAsEntry())) {
                            if (entry.isFile) {
                                _results.push(this.addFile(item.getAsFile()))
                            } else if (entry.isDirectory) {
                                _results.push(this._addFilesFromDirectory(entry, entry.name))
                            } else {
                                _results.push(void 0)
                            }
                        } else if (item.getAsFile != null) {
                            if (item.kind == null || item.kind === "file") {
                                _results.push(this.addFile(item.getAsFile()))
                            } else {
                                _results.push(void 0)
                            }
                        } else {
                            _results.push(void 0)
                        }
                    }
                    return _results
                };
                Dropzone.prototype._addFilesFromDirectory = function(directory, path) {
                    var dirReader, entriesReader, _this = this;
                    dirReader = directory.createReader();
                    entriesReader = function(entries) {
                        var entry, _i, _len;
                        for (_i = 0, _len = entries.length; _i < _len; _i++) {
                            entry = entries[_i];
                            if (entry.isFile) {
                                entry.file(function(file) {
                                    if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === ".") {
                                        return
                                    }
                                    file.fullPath = "" + path + "/" + file.name;
                                    return _this.addFile(file)
                                })
                            } else if (entry.isDirectory) {
                                _this._addFilesFromDirectory(entry, "" + path + "/" + entry.name)
                            }
                        }
                    };
                    return dirReader.readEntries(entriesReader,
                    function(error) {
                        return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0
                    })
                };
                Dropzone.prototype.accept = function(file, done) {
                    if (file.size > this.options.maxFilesize * 1024 * 1024) {
                        return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize))
                    } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
                        return done(this.options.dictInvalidFileType)
                    } else if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {
                        done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
                        return this.emit("maxfilesexceeded", file)
                    } else {
                        return this.options.accept.call(this, file, done)
                    }
                };
                Dropzone.prototype.addFile = function(file) {
                    var _this = this;
                    file.upload = {
                        progress: 0,
                        total: file.size,
                        bytesSent: 0
                    };
                    this.files.push(file);
                    file.status = Dropzone.ADDED;
                    this.emit("addedfile", file);
                    this._enqueueThumbnail(file);
                    return this.accept(file,
                    function(error) {
                        if (error) {
                            file.accepted = false;
                            _this._errorProcessing([file], error)
                        } else {
                            _this.enqueueFile(file)
                        }
                        return _this._updateMaxFilesReachedClass()
                    })
                };
                Dropzone.prototype.enqueueFiles = function(files) {
                    var file, _i, _len;
                    for (_i = 0, _len = files.length; _i < _len; _i++) {
                        file = files[_i];
                        this.enqueueFile(file)
                    }
                    return null
                };
                Dropzone.prototype.enqueueFile = function(file) {
                    var _this = this;
                    file.accepted = true;
                    if (file.status === Dropzone.ADDED) {
                        file.status = Dropzone.QUEUED;
                        if (this.options.autoProcessQueue) {
                            return setTimeout(function() {
                                return _this.processQueue()
                            },
                            0)
                        }
                    } else {
                        throw new Error("This file can't be queued because it has already been processed or was rejected.")
                    }
                };
                Dropzone.prototype._thumbnailQueue = [];
                Dropzone.prototype._processingThumbnail = false;
                Dropzone.prototype._enqueueThumbnail = function(file) {
                    var _this = this;
                    if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
                        this._thumbnailQueue.push(file);
                        return setTimeout(function() {
                            return _this._processThumbnailQueue()
                        },
                        0)
                    }
                };
                Dropzone.prototype._processThumbnailQueue = function() {
                    var _this = this;
                    if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
                        return
                    }
                    this._processingThumbnail = true;
                    return this.createThumbnail(this._thumbnailQueue.shift(),
                    function() {
                        _this._processingThumbnail = false;
                        return _this._processThumbnailQueue()
                    })
                };
                Dropzone.prototype.removeFile = function(file) {
                    if (file.status === Dropzone.UPLOADING) {
                        this.cancelUpload(file)
                    }
                    this.files = without(this.files, file);
                    this.emit("removedfile", file);
                    if (this.files.length === 0) {
                        return this.emit("reset")
                    }
                };
                Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {
                    var file, _i, _len, _ref;
                    if (cancelIfNecessary == null) {
                        cancelIfNecessary = false
                    }
                    _ref = this.files.slice();
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        file = _ref[_i];
                        if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
                            this.removeFile(file)
                        }
                    }
                    return null
                };
                Dropzone.prototype.createThumbnail = function(file, callback) {
                    var fileReader, _this = this;
                    fileReader = new FileReader;
                    fileReader.onload = function() {
                        var img;
                        img = document.createElement("img");
                        img.onload = function() {
                            var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3;
                            file.width = img.width;
                            file.height = img.height;
                            resizeInfo = _this.options.resize.call(_this, file);
                            if (resizeInfo.trgWidth == null) {
                                resizeInfo.trgWidth = _this.options.thumbnailWidth
                            }
                            if (resizeInfo.trgHeight == null) {
                                resizeInfo.trgHeight = _this.options.thumbnailHeight
                            }
                            canvas = document.createElement("canvas");
                            ctx = canvas.getContext("2d");
                            canvas.width = resizeInfo.trgWidth;
                            canvas.height = resizeInfo.trgHeight;
                            drawImageIOSFix(ctx, img, (_ref = resizeInfo.srcX) != null ? _ref: 0, (_ref1 = resizeInfo.srcY) != null ? _ref1: 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2: 0, (_ref3 = resizeInfo.trgY) != null ? _ref3: 0, resizeInfo.trgWidth, resizeInfo.trgHeight);
                            thumbnail = canvas.toDataURL("image/png");
                            _this.emit("thumbnail", file, thumbnail);
                            if (callback != null) {
                                return callback()
                            }
                        };
                        return img.src = fileReader.result
                    };
                    return fileReader.readAsDataURL(file)
                };
                Dropzone.prototype.processQueue = function() {
                    var i, parallelUploads, processingLength, queuedFiles;
                    parallelUploads = this.options.parallelUploads;
                    processingLength = this.getUploadingFiles().length;
                    i = processingLength;
                    if (processingLength >= parallelUploads) {
                        return
                    }
                    queuedFiles = this.getQueuedFiles();
                    if (! (queuedFiles.length > 0)) {
                        return
                    }
                    if (this.options.uploadMultiple) {
                        return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength))
                    } else {
                        while (i < parallelUploads) {
                            if (!queuedFiles.length) {
                                return
                            }
                            this.processFile(queuedFiles.shift());
                            i++
                        }
                    }
                };
                Dropzone.prototype.processFile = function(file) {
                    return this.processFiles([file])
                };
                Dropzone.prototype.processFiles = function(files) {
                    var file, _i, _len;
                    for (_i = 0, _len = files.length; _i < _len; _i++) {
                        file = files[_i];
                        file.processing = true;
                        file.status = Dropzone.UPLOADING;
                        this.emit("processing", file)
                    }
                    if (this.options.uploadMultiple) {
                        this.emit("processingmultiple", files)
                    }
                    return this.uploadFiles(files)
                };
                Dropzone.prototype._getFilesWithXhr = function(xhr) {
                    var file, files;
                    return files = function() {
                        var _i, _len, _ref, _results;
                        _ref = this.files;
                        _results = [];
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            file = _ref[_i];
                            if (file.xhr === xhr) {
                                _results.push(file)
                            }
                        }
                        return _results
                    }.call(this)
                };
                Dropzone.prototype.cancelUpload = function(file) {
                    var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref;
                    if (file.status === Dropzone.UPLOADING) {
                        groupedFiles = this._getFilesWithXhr(file.xhr);
                        for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) {
                            groupedFile = groupedFiles[_i];
                            groupedFile.status = Dropzone.CANCELED
                        }
                        file.xhr.abort();
                        for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) {
                            groupedFile = groupedFiles[_j];
                            this.emit("canceled", groupedFile)
                        }
                        if (this.options.uploadMultiple) {
                            this.emit("canceledmultiple", groupedFiles)
                        }
                    } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) {
                        file.status = Dropzone.CANCELED;
                        this.emit("canceled", file);
                        if (this.options.uploadMultiple) {
                            this.emit("canceledmultiple", [file])
                        }
                    }
                    if (this.options.autoProcessQueue) {
                        return this.processQueue()
                    }
                };
                Dropzone.prototype.uploadFile = function(file) {
                    return this.uploadFiles([file])
                };
                Dropzone.prototype.uploadFiles = function(files) {
                    var file, formData, handleError, headerName, headerValue, headers, input, inputName, inputType, key, option, progressObj, response, updateProgress, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _this = this;
                    xhr = new XMLHttpRequest;
                    for (_i = 0, _len = files.length; _i < _len; _i++) {
                        file = files[_i];
                        file.xhr = xhr
                    }
                    xhr.open(this.options.method, this.options.url, true);
                    xhr.withCredentials = !!this.options.withCredentials;
                    response = null;
                    handleError = function() {
                        var _j, _len1, _results;
                        _results = [];
                        for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
                            file = files[_j];
                            _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr))
                        }
                        return _results
                    };
                    updateProgress = function(e) {
                        var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results;
                        if (e != null) {
                            progress = 100 * e.loaded / e.total;
                            for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
                                file = files[_j];
                                file.upload = {
                                    progress: progress,
                                    total: e.total,
                                    bytesSent: e.loaded
                                }
                            }
                        } else {
                            allFilesFinished = true;
                            progress = 100;
                            for (_k = 0, _len2 = files.length; _k < _len2; _k++) {
                                file = files[_k];
                                if (! (file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) {
                                    allFilesFinished = false
                                }
                                file.upload.progress = progress;
                                file.upload.bytesSent = file.upload.total
                            }
                            if (allFilesFinished) {
                                return
                            }
                        }
                        _results = [];
                        for (_l = 0, _len3 = files.length; _l < _len3; _l++) {
                            file = files[_l];
                            _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent))
                        }
                        return _results
                    };
                    xhr.onload = function(e) {
                        var _ref;
                        if (files[0].status === Dropzone.CANCELED) {
                            return
                        }
                        if (xhr.readyState !== 4) {
                            return
                        }
                        response = xhr.responseText;
                        if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
                            try {
                                response = JSON.parse(response)
                            } catch(_error) {
                                e = _error;
                                response = "Invalid JSON response from server."
                            }
                        }
                        updateProgress();
                        if (! (200 <= (_ref = xhr.status) && _ref < 300)) {
                            return handleError()
                        } else {
                            return _this._finished(files, response, e)
                        }
                    };
                    xhr.onerror = function() {
                        if (files[0].status === Dropzone.CANCELED) {
                            return
                        }
                        return handleError()
                    };
                    progressObj = (_ref = xhr.upload) != null ? _ref: xhr;
                    progressObj.onprogress = updateProgress;
                    headers = {
                        Accept: "application/json",
                        "Cache-Control": "no-cache",
                        "X-Requested-With": "XMLHttpRequest"
                    };
                    if (this.options.headers) {
                        extend(headers, this.options.headers)
                    }
                    for (headerName in headers) {
                        headerValue = headers[headerName];
                        xhr.setRequestHeader(headerName, headerValue)
                    }
                    formData = new FormData;
                    if (this.options.params) {
                        _ref1 = this.options.params;
                        for (key in _ref1) {
                            value = _ref1[key];
                            formData.append(key, value)
                        }
                    }
                    for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
                        file = files[_j];
                        this.emit("sending", file, xhr, formData)
                    }
                    if (this.options.uploadMultiple) {
                        this.emit("sendingmultiple", files, xhr, formData)
                    }
                    if (this.element.tagName === "FORM") {
                        _ref2 = this.element.querySelectorAll("input, textarea, select, button");
                        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
                            input = _ref2[_k];
                            inputName = input.getAttribute("name");
                            inputType = input.getAttribute("type");
                            if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
                                _ref3 = input.options;
                                for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
                                    option = _ref3[_l];
                                    if (option.selected) {
                                        formData.append(inputName, option.value)
                                    }
                                }
                            } else if (!inputType || (_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio" || input.checked) {
                                formData.append(inputName, input.value)
                            }
                        }
                    }
                    for (_m = 0, _len4 = files.length; _m < _len4; _m++) {
                        file = files[_m];
                        formData.append("" + this.options.paramName + (this.options.uploadMultiple ? "[]": ""), file, file.name)
                    }
                    return xhr.send(formData)
                };
                Dropzone.prototype._finished = function(files, responseText, e) {
                    var file, _i, _len;
                    for (_i = 0, _len = files.length; _i < _len; _i++) {
                        file = files[_i];
                        file.status = Dropzone.SUCCESS;
                        this.emit("success", file, responseText, e);
                        this.emit("complete", file)
                    }
                    if (this.options.uploadMultiple) {
                        this.emit("successmultiple", files, responseText, e);
                        this.emit("completemultiple", files)
                    }
                    if (this.options.autoProcessQueue) {
                        return this.processQueue()
                    }
                };
                Dropzone.prototype._errorProcessing = function(files, message, xhr) {
                    var file, _i, _len;
                    for (_i = 0, _len = files.length; _i < _len; _i++) {
                        file = files[_i];
                        file.status = Dropzone.ERROR;
                        this.emit("error", file, message, xhr);
                        this.emit("complete", file)
                    }
                    if (this.options.uploadMultiple) {
                        this.emit("errormultiple", files, message, xhr);
                        this.emit("completemultiple", files)
                    }
                    if (this.options.autoProcessQueue) {
                        return this.processQueue()
                    }
                };
                return Dropzone
            } (Em);
            Dropzone.version = "3.8.4";
            Dropzone.options = {};
            Dropzone.optionsForElement = function(element) {
                if (element.getAttribute("id")) {
                    return Dropzone.options[camelize(element.getAttribute("id"))]
                } else {
                    return void 0
                }
            };
            Dropzone.instances = [];
            Dropzone.forElement = function(element) {
                if (typeof element === "string") {
                    element = document.querySelector(element)
                }
                if ((element != null ? element.dropzone: void 0) == null) {
                    throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.")
                }
                return element.dropzone
            };
            Dropzone.autoDiscover = true;
            Dropzone.discover = function() {
                var checkElements, dropzone, dropzones, _i, _len, _results;
                if (document.querySelectorAll) {
                    dropzones = document.querySelectorAll(".dropzone")
                } else {
                    dropzones = [];
                    checkElements = function(elements) {
                        var el, _i, _len, _results;
                        _results = [];
                        for (_i = 0, _len = elements.length; _i < _len; _i++) {
                            el = elements[_i];
                            if (/(^| )dropzone($| )/.test(el.className)) {
                                _results.push(dropzones.push(el))
                            } else {
                                _results.push(void 0)
                            }
                        }
                        return _results
                    };
                    checkElements(document.getElementsByTagName("div"));
                    checkElements(document.getElementsByTagName("form"))
                }
                _results = [];
                for (_i = 0, _len = dropzones.length; _i < _len; _i++) {
                    dropzone = dropzones[_i];
                    if (Dropzone.optionsForElement(dropzone) !== false) {
                        _results.push(new Dropzone(dropzone))
                    } else {
                        _results.push(void 0)
                    }
                }
                return _results
            };
            Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i];
            Dropzone.isBrowserSupported = function() {
                var capableBrowser, regex, _i, _len, _ref;
                capableBrowser = true;
                if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
                    if (! ("classList" in document.createElement("a"))) {
                        capableBrowser = false
                    } else {
                        _ref = Dropzone.blacklistedBrowsers;
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            regex = _ref[_i];
                            if (regex.test(navigator.userAgent)) {
                                capableBrowser = false;
                                continue
                            }
                        }
                    }
                } else {
                    capableBrowser = false
                }
                return capableBrowser
            };
            without = function(list, rejectedItem) {
                var item, _i, _len, _results;
                _results = [];
                for (_i = 0, _len = list.length; _i < _len; _i++) {
                    item = list[_i];
                    if (item !== rejectedItem) {
                        _results.push(item)
                    }
                }
                return _results
            };
            camelize = function(str) {
                return str.replace(/[\-_](\w)/g,
                function(match) {
                    return match[1].toUpperCase()
                })
            };
            Dropzone.createElement = function(string) {
                var div;
                div = document.createElement("div");
                div.innerHTML = string;
                return div.childNodes[0]
            };
            Dropzone.elementInside = function(element, container) {
                if (element === container) {
                    return true
                }
                while (element = element.parentNode) {
                    if (element === container) {
                        return true
                    }
                }
                return false
            };
            Dropzone.getElement = function(el, name) {
                var element;
                if (typeof el === "string") {
                    element = document.querySelector(el)
                } else if (el.nodeType != null) {
                    element = el
                }
                if (element == null) {
                    throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.")
                }
                return element
            };
            Dropzone.getElements = function(els, name) {
                var e, el, elements, _i, _j, _len, _len1, _ref;
                if (els instanceof Array) {
                    elements = [];
                    try {
                        for (_i = 0, _len = els.length; _i < _len; _i++) {
                            el = els[_i];
                            elements.push(this.getElement(el, name))
                        }
                    } catch(_error) {
                        e = _error;
                        elements = null
                    }
                } else if (typeof els === "string") {
                    elements = [];
                    _ref = document.querySelectorAll(els);
                    for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
                        el = _ref[_j];
                        elements.push(el)
                    }
                } else if (els.nodeType != null) {
                    elements = [els]
                }
                if (! (elements != null && elements.length)) {
                    throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.")
                }
                return elements
            };
            Dropzone.confirm = function(question, accepted, rejected) {
                if (window.confirm(question)) {
                    return accepted()
                } else if (rejected != null) {
                    return rejected()
                }
            };
            Dropzone.isValidFile = function(file, acceptedFiles) {
                var baseMimeType, mimeType, validType, _i, _len;
                if (!acceptedFiles) {
                    return true
                }
                acceptedFiles = acceptedFiles.split(",");
                mimeType = file.type;
                baseMimeType = mimeType.replace(/\/.*$/, "");
                for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) {
                    validType = acceptedFiles[_i];
                    validType = validType.trim();
                    if (validType.charAt(0) === ".") {
                        if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
                            return true
                        }
                    } else if (/\/\*$/.test(validType)) {
                        if (baseMimeType === validType.replace(/\/.*$/, "")) {
                            return true
                        }
                    } else {
                        if (mimeType === validType) {
                            return true
                        }
                    }
                }
                return false
            };
            if (typeof jQuery !== "undefined" && jQuery !== null) {
                jQuery.fn.dropzone = function(options) {
                    return this.each(function() {
                        return new Dropzone(this, options)
                    })
                }
            }
            if (typeof module !== "undefined" && module !== null) {
                module.exports = Dropzone
            } else {
                window.Dropzone = Dropzone
            }
            Dropzone.ADDED = "added";
            Dropzone.QUEUED = "queued";
            Dropzone.ACCEPTED = Dropzone.QUEUED;
            Dropzone.UPLOADING = "uploading";
            Dropzone.PROCESSING = Dropzone.UPLOADING;
            Dropzone.CANCELED = "canceled";
            Dropzone.ERROR = "error";
            Dropzone.SUCCESS = "success";
            detectVerticalSquash = function(img) {
                var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy;
                iw = img.naturalWidth;
                ih = img.naturalHeight;
                canvas = document.createElement("canvas");
                canvas.width = 1;
                canvas.height = ih;
                ctx = canvas.getContext("2d");
                ctx.drawImage(img, 0, 0);
                data = ctx.getImageData(0, 0, 1, ih).data;
                sy = 0;
                ey = ih;
                py = ih;
                while (py > sy) {
                    alpha = data[(py - 1) * 4 + 3];
                    if (alpha === 0) {
                        ey = py
                    } else {
                        sy = py
                    }
                    py = ey + sy >> 1
                }
                ratio = py / ih;
                if (ratio === 0) {
                    return 1
                } else {
                    return ratio
                }
            };
            drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
                var vertSquashRatio;
                vertSquashRatio = detectVerticalSquash(img);
                return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio)
            };
            contentLoaded = function(win, fn) {
                var add, doc, done, init, poll, pre, rem, root, top;
                done = false;
                top = true;
                doc = win.document;
                root = doc.documentElement;
                add = doc.addEventListener ? "addEventListener": "attachEvent";
                rem = doc.addEventListener ? "removeEventListener": "detachEvent";
                pre = doc.addEventListener ? "": "on";
                init = function(e) {
                    if (e.type === "readystatechange" && doc.readyState !== "complete") {
                        return
                    } (e.type === "load" ? win: doc)[rem](pre + e.type, init, false);
                    if (!done && (done = true)) {
                        return fn.call(win, e.type || e)
                    }
                };
                poll = function() {
                    var e;
                    try {
                        root.doScroll("left")
                    } catch(_error) {
                        e = _error;
                        setTimeout(poll, 50);
                        return
                    }
                    return init("poll")
                };
                if (doc.readyState !== "complete") {
                    if (doc.createEventObject && root.doScroll) {
                        try {
                            top = !win.frameElement
                        } catch(_error) {}
                        if (top) {
                            poll()
                        }
                    }
                    doc[add](pre + "DOMContentLoaded", init, false);
                    doc[add](pre + "readystatechange", init, false);
                    return win[add](pre + "load", init, false)
                }
            };
            Dropzone._autoDiscoverFunction = function() {
                if (Dropzone.autoDiscover) {
                    return Dropzone.discover()
                }
            };
            contentLoaded(window, Dropzone._autoDiscoverFunction)
        }).call(this)
    });
    require.alias("component-emitter/index.js", "dropzone/deps/emitter/index.js");
    require.alias("component-emitter/index.js", "emitter/index.js");
    if (typeof exports == "object") {
        module.exports = require("dropzone")
    } else if (typeof define == "function" && define.amd) {
        define(function() {
            return require("dropzone")
        })
    } else {
        this["Dropzone"] = require("dropzone")
    }
})(); (function($) {
    $.fn.equalHeights = function() {
        var maxHeight = 0,
        $this = $(this);
        $this.each(function() {
            $this.removeAttr("style");
            var height = $(this).innerHeight();
            if (height > maxHeight) {
                maxHeight = height
            }
        });
        return $this.css("min-height", maxHeight)
    };
    $.initEqualHeights = function() {
        setTimeout(function() {
            $("[data-equal]").each(function() {
                var $this = $(this),
                target = $this.data("equal");
                $this.find(target).equalHeights()
            })
        },
        10)
    };
    $(window).load(function() {
        $.initEqualHeights()
    });
    $(window).resize(function() {
        $.initEqualHeights()
    })
})(jQuery); (function() {
    var regexEscape = function(str) {
        return (str + "").replace(/[\-#$\^*()+\[\]{}|\\,.?\s]/g, "\\$&")
    };
    var HTML = [{
        "char": "&",
        html: "&amp;",
        charRegex: /&/g,
        htmlRegex: /&amp;/g
    },
    {
        "char": "<",
        html: "&lt;",
        charRegex: /</g,
        htmlRegex: /&lt;/g
    },
    {
        "char": ">",
        html: "&gt;",
        charRegex: />/g,
        htmlRegex: /&gt;/g
    },
    {
        "char": '"',
        html: "&quot;",
        charRegex: /"/g,
        htmlRegex: /&quot;/g
    },
    {
        "char": "'",
        html: "&#x27;",
        charRegex: /'/g,
        htmlRegex: /&\#x27;/g
    },
    {
        "char": "/",
        html: "&#x2F;",
        charRegex: /\//g,
        htmlRegex: /&\#x2F;/g
    },
    {
        "char": "`",
        html: "&#x60;",
        charRegex: /`/g,
        htmlRegex: /&\#x60;/g
    }];
    var encode = function(str) {
        str = str + "";
        for (var i = 0; i < HTML.length; i++) {
            str = str.replace(HTML[i].charRegex, HTML[i].html)
        }
        return str
    };
    var decode = function(str) {
        str = str + "";
        for (var i = 0; i < HTML.length; i++) {
            str = str.replace(HTML[i].htmlRegex, HTML[i]["char"])
        }
        return str
    };
    window["AutoComplete"] = window["AutoComplete"] ||
    function(containerElOrId, cfg) {
        "use strict";
        var AJAX_BUFFER_LENGTH = 200,
        HTML_SENTINELS = [],
        LOCAL_STORAGE_AVAILABLE = false,
        MINIMUM_JQUERY_VERSION = "1.4.2";
        var KEYS = {
            BACKSPACE: 8,
            TAB: 9,
            ENTER: 13,
            ESCAPE: 27,
            LEFT: 37,
            UP: 38,
            RIGHT: 39,
            DOWN: 40,
            DELETE: 46,
            NUMPAD_ENTER: 108
        };
        var containerEl, dropdownEl, inputEl, placeholderEl, tokensEl, inputWidthProxyEl;
        var CSS = {
            ajaxError: "ajax-error-8fd89",
            ajaxLoading: "ajax-loading-72914",
            autocompleteContainer: "autocomplete-container-7a26d",
            childrenIndicator: "children-indicator-ca540",
            clear: "clear-53545",
            dropdown: "dropdown-a3d44",
            firstOption: "first-option-96d82",
            highlightedOption: "highlighted-ea4c1",
            input: "input-8f2fe",
            inputWidthProxy: "input-width-proxy-1c13e",
            lastOption: "last-option-c1e64",
            listItem: "list-item-d13e9",
            noResults: "no-results-902b5",
            option: "option-7b59f",
            placeholder: "placeholder-d722a",
            removeTokenGroup: "remove-token-group-53474",
            selectedTokenGroup: "selected-token-group-359b9",
            tokensContainer: "tokens-6a7a0",
            token: "token-75233",
            tokenGroup: "token-group-c7334",
            tokenSeparator: "token-separator-359b9"
        };
        var CSS_TEXT_PROPS = ["font-family", "font-feature-settings", "font-kerning", "font-language-override", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-variant-ligatures", "font-weight", "word-spacing", "letter-spacing", "white-space", "word-wrap", "word-break", "text-align", "text-align-last", "text-combine-horizontal", "text-decoration", "text-decoration-color", "text-decoration-line", "text-decoration-style", "text-indent", "text-orientation", "text-overflow", "text-rendering", "text-shadow", "text-transform", "text-underline-position"];
        var ADD_NEXT_TOKEN_TO_NEW_TOKEN_GROUP = true,
        AJAX_BUFFER_TIMEOUT, AJAX_OBJECT = {},
        CURRENT_LIST_NAME = false,
        INPUT_HAS_FOCUS = false,
        OPTIONS_SHOWING = false,
        SESSION_CACHE = {},
        TOKENS = [],
        VISIBLE_OPTIONS = {};
        var widget = {};
        var createId = function() {
            return "xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx".replace(/x/g,
            function(c) {
                var r = Math.random() * 16 | 0;
                return r.toString(16)
            })
        };
        var deepCopy = function(thing) {
            return JSON.parse(JSON.stringify(thing))
        };
        var parseSemVer = function(version) {
            var tmp = version.split(".");
            return {
                major: parseInt(tmp[0], 10),
                minor: parseInt(tmp[1], 10),
                patch: parseInt(tmp[2], 10)
            }
        };
        var compareSemVer = function(version, minimum) {
            version = parseSemVer(version);
            minimum = parseSemVer(minimum);
            var versionNum = version.major * 1e4 * 1e4 + version.minor * 1e4 + version.patch;
            var minimumNum = minimum.major * 1e4 * 1e4 + minimum.minor * 1e4 + minimum.patch;
            return versionNum >= minimumNum
        };
        LOCAL_STORAGE_AVAILABLE = function() {
            var str = createId();
            try {
                localStorage.setItem(str, str);
                localStorage.removeItem(str);
                return true
            } catch(e) {
                return false
            }
        } ();
        var isArray = Array.isArray ||
        function(vArg) {
            return Object.prototype.toString.call(vArg) === "[object Array]"
        };
        var isObject = $.isPlainObject;
        var keys = function(obj) {
            var arr = [];
            for (var i in obj) {
                if (obj.hasOwnProperty(i) !== true) continue;
                arr.push(i)
            }
            return arr
        };
        var tmpl = function(str, obj, htmlEscape) {
            if (htmlEscape !== true) {
                htmlEscape = false
            }
            for (var i in obj) {
                if (obj.hasOwnProperty(i) !== true) continue;
                var value = obj[i] + "";
                if (htmlEscape === true) {
                    value = encode(value)
                }
                str = str.replace(new RegExp("{" + regexEscape(i) + "}", "g"), value)
            }
            return str
        };
        var now = function() {
            return parseInt((new Date).getTime() / 1e3, 10)
        };
        var storeInCache = function(key, data, duration) {
            data = JSON.stringify(data);
            var expires = "never";
            if (typeof duration === "number") {
                expires = now() + duration
            }
            var localStorageSucceeded = false;
            if (LOCAL_STORAGE_AVAILABLE === true) {
                try {
                    localStorage.setItem(key, data);
                    localStorage.setItem(key + " expires", expires);
                    localStorageSucceeded = true
                } catch(e) {}
            }
            if (localStorageSucceeded === false) {
                SESSION_CACHE[key] = data;
                SESSION_CACHE[key + " expires"] = expires
            }
        };
        var isExpired = function(time) {
            if (time === "never") {
                return false
            }
            return parseInt(time, 10) <= now()
        };
        var getFromCache = function(key) {
            var data, expireTime, expiresKey = key + " expires",
            localStorageSucceeded = false;
            if (LOCAL_STORAGE_AVAILABLE === true) {
                try {
                    data = localStorage.getItem(key);
                    expireTime = localStorage.getItem(expiresKey);
                    localStorageSucceeded = true
                } catch(e) {}
                if (localStorageSucceeded === true && isExpired(expireTime) === false && typeof data === "string") {
                    return JSON.parse(data)
                } else {
                    localStorageSucceeded = false
                }
            }
            if (localStorageSucceeded === false) {
                if (SESSION_CACHE.hasOwnProperty(expiresKey) === true) {
                    expireTime = SESSION_CACHE[expiresKey];
                    if (SESSION_CACHE.hasOwnProperty(key) === true && isExpired(expireTime) === false && typeof SESSION_CACHE[key] === "string") {
                        return JSON.parse(SESSION_CACHE[key])
                    }
                }
            }
            return false
        }; (function() {
            for (var i = 0; i < HTML.length; i++) {
                var id = createId();
                HTML_SENTINELS[i] = {
                    sentinel: id,
                    sentinelRegex: new RegExp(regexEscape(id), "g")
                }
            }
        })();
        var validListName = function(name) {
            return typeof name === "string" && name !== ""
        };
        var validTokenGroupIndex = function(index) {
            if (typeof index !== "number") {
                return false
            }
            index = parseInt(index, 10);
            if (index < 0 || index >= TOKENS.length) {
                return false
            }
            return true
        };
        var validToken = function(token) {
            if (typeof token === "string") {
                return true
            }
            if (isObject(token) !== true || token.hasOwnProperty("value") !== true || token.hasOwnProperty("tokenHTML") !== true || typeof token.tokenHTML !== "string") {
                return false
            }
            return true
        };
        var validTokenGroup = function(tokenGroup) {
            if (isArray(tokenGroup) !== true) {
                return false
            }
            if (tokenGroup.length === 0) {
                return false
            }
            for (var i = 0; i < tokenGroup.length; i++) {
                if (validToken(tokenGroup[i]) !== true) {
                    return false
                }
            }
            return true
        };
        var validValue = function(value) {
            if (validToken(value) === true) {
                return true
            }
            if (validTokenGroup(value) === true) {
                return true
            }
            if (isArray(value) !== true) {
                return false
            }
            for (var i = 0; i < value.length; i++) {
                if (validTokenGroup(value[i]) !== true) {
                    return false
                }
            }
            return true
        };
        var validOptionObject = function(option) {
            if (typeof option === "string") {
                return true
            }
            if (isObject(option) !== true || option.hasOwnProperty("value") !== true) {
                return false
            }
            return true
        };
        var validListObject = function(obj) {
            if (typeof obj === "string") {
                return true
            }
            if (isArray(obj) === true) {
                for (var i = 0; i < obj.length; i++) {
                    if (validOptionObject(obj[i]) !== true) {
                        return false
                    }
                }
                return true
            }
            if (isObject(obj) !== true) {
                return false
            }
            return true
        };
        var error = function(code, msg, obj) {
            if (cfg.hasOwnProperty("showErrors") !== true || cfg.showErrors === false) {
                return
            }
            var errorText = "AutoComplete Error " + code + ": " + msg;
            if (cfg.showErrors === "console" && typeof console === "object" && typeof console.log === "function") {
                console.log(errorText);
                if (arguments.length >= 2) {
                    console.log(obj)
                }
                return
            }
            if (cfg.showErrors === "alert") {
                if (obj) {
                    errorText += "\n\n" + JSON.stringify(obj)
                }
                window.alert(errorText);
                return
            }
            if (typeof cfg.showErrors === "function") {
                cfg.showErrors(code, msg, obj)
            }
        };
        var sanityChecks = function() {
            if (typeof containerElOrId === "string") {
                if (containerElOrId === "") {
                    window.alert("AutoComplete Error 1037: " + "The first argument to AutoComplete() cannot be an empty string." + "\n\nExiting...");
                    return false
                }
                var el = document.getElementById(containerElOrId);
                if (!el) {
                    window.alert('AutoComplete Error 1002: Element with id "' + containerElOrId + '" does not exist in the DOM.' + "\n\nExiting...");
                    return false
                }
                containerEl = $(el)
            } else {
                containerEl = $(containerElOrId);
                if (containerEl.length !== 1) {
                    window.alert("AutoComplete Error 1044: The first argument to " + "AutoComplete() must be an ID or a single DOM node." + "\n\nExiting...");
                    return false
                }
            }
            if (!window.JSON || typeof JSON.stringify !== "function" || typeof JSON.parse !== "function") {
                window.alert("AutoComplete Error 1003: JSON does not exist. " + "Please include a JSON polyfill.\n\nExiting...");
                return false
            }
            if (! (typeof window.$ && $.fn && $.fn.jquery && compareSemVer($.fn.jquery, MINIMUM_JQUERY_VERSION) === true)) {
                window.alert("AutoComplete Error 1004: Unable to find a valid version " + "of jQuery. Please include jQuery " + MINIMUM_JQUERY_VERSION + " or " + "higher on the page.\n\nExiting...");
                return false
            }
            return expandConfig()
        };
        var expandTokenObject = function(token) {
            if (typeof token === "string") {
                token = {
                    tokenHTML: encode(token),
                    value: token
                }
            }
            return token
        };
        var expandTokenGroup = function(group) {
            for (var i = 0; i < group.length; i++) {
                group[i] = expandTokenObject(group[i])
            }
            return group
        };
        var expandValue = function(value) {
            if (validToken(value) === true) {
                return [[expandTokenObject(value)]]
            }
            if (validTokenGroup(value) === true) {
                return [expandTokenGroup(value)]
            }
            for (var i = 0; i < value.length; i++) {
                value[i] = expandTokenGroup(value[i])
            }
            return value
        };
        var expandOptionObject = function(option, parentList) {
            if (typeof option === "string" || typeof option === "number") {
                option = {
                    optionHTML: encode(option),
                    tokenHTML: encode(option),
                    value: option
                };
                return option
            }
            option.optionHTML = buildOptionHTML(option, parentList);
            option.tokenHTML = buildTokenHTML(option, parentList);
            return option
        };
        var expandListObject = function(list) {
            if (isArray(list) === true) {
                list = {
                    options: list
                }
            }
            if (typeof list === "string") {
                list = {
                    ajaxOpts: {
                        url: list
                    }
                }
            }
            list.ajaxEnabled = false;
            if (list.hasOwnProperty("ajaxOpts") === true && (typeof list.ajaxOpts === "function" || isObject(list.ajaxOpts) === true)) {
                list.ajaxEnabled = true
            }
            if (typeof list.ajaxErrorHTML !== "string" && typeof list.ajaxErrorHTML !== "function") {
                list.ajaxErrorHTML = "AJAX Error"
            }
            if (typeof list.ajaxLoadingHTML !== "string" && typeof list.ajaxLoadingHTML !== "function") {
                list.ajaxLoadingHTML = "Searching&hellip;"
            }
            if (list.allowFreeform !== true) {
                list.allowFreeform = false
            }
            if (list.cacheAjax !== true) {
                list.cacheAjax = false
            }
            if (list.cacheAjaxSeconds !== false && typeof list.cacheAjaxSeconds !== "number") {
                list.cacheAjaxSeconds = 1209600
            }
            if (typeof list.cacheAjaxSeconds === "number") {
                list.cacheAjaxSeconds = parseInt(list.cacheAjaxSeconds, 10)
            }
            if (list.highlightMatches !== false) {
                list.highlightMatches = true
            }
            if (typeof list.noResultsHTML !== "string" && typeof list.noResultsHTML !== "function") {
                list.noResultsHTML = "No results found."
            }
            if (isArray(list.options) !== true) {
                list.options = []
            }
            for (var i = 0; i < list.options.length; i++) {
                list.options[i] = expandOptionObject(list.options[i], list)
            }
            return list
        };
        var expandConfig = function() {
            if (isArray(cfg) === true || typeof cfg === "string") {
                cfg = {
                    lists: {
                        "default": cfg
                    }
                }
            }
            if (typeof cfg.ajaxBuffer === "number" && cfg.ajaxBuffer > 0) {
                AJAX_BUFFER_LENGTH = cfg.ajaxBuffer
            }
            if (typeof cfg.maxTokenGroups !== "number" || cfg.maxTokenGroups < 0) {
                cfg.maxTokenGroups = false
            }
            if (typeof cfg.maxTokenGroups === "number") {
                cfg.maxTokenGroups = parseInt(cfg.maxTokenGroups, 10)
            }
            if (typeof cfg.onChange !== "function") {
                cfg.onChange = false
            }
            if (cfg.hasOwnProperty("initialValue") === true) {
                if (validValue(cfg.initialValue) === true) {
                    TOKENS = deepCopy(expandValue(cfg.initialValue))
                } else {
                    error(6447, "Invalid value passed to initialValue.", cfg.initialValue)
                }
            }
            if (typeof cfg.placeholderHTML !== "string") {
                cfg.placeholderHTML = ""
            }
            if (typeof cfg.tokenSeparatorHTML !== "string" && typeof cfg.tokenSeparatorHTML !== "function") {
                cfg.tokenSeparatorHTML = ":"
            }
            if (cfg.showErrors !== "console" && cfg.showErrors !== "alert" && typeof cfg.showErrors !== "function") {
                cfg.showErrors = false
            }
            for (var i in cfg.lists) {
                if (cfg.lists.hasOwnProperty(i) !== true) continue;
                if (validListName(i) !== true) {
                    error(2642, "You cannot use an empty string for a list name.");
                    delete cfg.lists[i];
                    continue
                }
                if (validListObject(cfg.lists[i]) === true) {
                    cfg.lists[i] = expandListObject(cfg.lists[i])
                } else {
                    error(2535, 'The list object for list "' + i + '" is invalid.', cfg.lists[i]);
                    delete cfg.lists[i]
                }
            }
            var listNames = keys(cfg.lists);
            if (listNames.length === 0) {
                window.alert("AutoComplete Error 1005: " + "You must include at least one List Object on lists.\n\nExiting...");
                return false
            }
            if (listNames.length === 1) {
                cfg.initialList = listNames[0]
            }
            if (listExists(cfg.initialList) !== true) {
                error(2728, 'initialList "' + cfg.initialList + '" does not exist ' + "on the lists object.");
                cfg.initialList = listNames[0]
            }
            CURRENT_LIST_NAME = cfg.initialList;
            return true
        };
        var buildWidget = function() {
            var html = '<div class="' + CSS.autocompleteContainer + '">' + '<div class="' + CSS.placeholder + '"></div>' + '<div class="' + CSS.tokensContainer + '"></div>' + '<input type="text" class="' + CSS.input + '" />' + '<div class="' + CSS.clear + '"></div>' + '<ul class="' + CSS.dropdown + '" style="display:none"></ul>' + "</div>" + '<span class="' + CSS.inputWidthProxy + '" style="position:absolute; ' + 'top:-9999px;"></span>';
            return html
        };
        var buildOptionHTML = function(option, parentList) {
            if (typeof option.optionHTML === "string") {
                return option.optionHTML
            }
            if (typeof parentList.optionHTML === "string" && isObject(option.value) === true) {
                return tmpl(parentList.optionHTML, option.value, true)
            }
            if (typeof parentList.optionHTML === "function") {
                var html = parentList.optionHTML(option);
                if (typeof html === "string") {
                    return html
                }
                error(3843, "optionHTML function did not return a string.", option)
            }
            if (typeof option.value === "string" || typeof option.value === "number") {
                return encode(option.value)
            }
            if (isObject(option.value) === true) {
                for (var i in option.value) {
                    if (option.hasOwnProperty(i) !== true) continue;
                    if (typeof option[i] === "string") {
                        error(3193, "Could not find a valid value for optionHTML. " + 'Resorted to using value property "' + i + '"', option);
                        return encode(option[i])
                    }
                }
            }
            error(5783, "Unable to create HTML string for optionHTML.", option);
            return "<em>unknown option</em>"
        };
        var buildOption = function(option, parentList) {
            var optionId = createId();
            VISIBLE_OPTIONS[optionId] = option;
            var childrenListName = getChildrenListName(option, parentList);
            var html = '<li class="' + CSS.listItem + " " + CSS.option + '" ' + 'data-option-id="' + encode(optionId) + '">' + option.optionHTML;
            if (typeof childrenListName === "string") {
                html += '<span class="' + CSS.childrenIndicator + '">&#x25B8;</span>'
            }
            html += "</li>";
            return html
        };
        var buildOptions = function(options, parentList, appendVisibleOptions) {
            if (appendVisibleOptions !== true) {
                VISIBLE_OPTIONS = {}
            }
            var html = "";
            for (var i = 0,
            len = options.length; i < len; i++) {
                html += buildOption(options[i], parentList)
            }
            return html
        };
        var buildTokenHTML = function(option, parentList) {
            if (typeof option.tokenHTML === "string") {
                return option.tokenHTML
            }
            if (typeof parentList.tokenHTML === "string" && isObject(option.value) === true) {
                return tmpl(parentList.tokenHTML, option.value, true)
            }
            if (typeof parentList.tokenHTML === "function") {
                return parentList.tokenHTML(option)
            }
            return buildOptionHTML(option, parentList)
        };
        var buildTokens = function(tokens) {
            var html = "";
            for (var i = 0; i < tokens.length; i++) {
                var tokenGroup = tokens[i];
                html += '<div class="' + CSS.tokenGroup + '"' + ' data-token-group-index="' + i + '">' + '<span class="' + CSS.removeTokenGroup + '">&times;</span>';
                for (var j = 0; j < tokenGroup.length; j++) {
                    html += '<span class="' + CSS.token + '">' + tokenGroup[j].tokenHTML + "</span>";
                    if (j !== tokenGroup.length - 1) {
                        html += '<span class="' + CSS.tokenSeparator + '">';
                        if (typeof cfg.tokenSeparatorHTML === "string") {
                            html += cfg.tokenSeparatorHTML
                        }
                        if (typeof cfg.tokenSeparatorHTML === "function") {
                            var customTokenSeparator = cfg.tokenSeparatorHTML(tokenGroup[j], tokenGroup[j + 1]);
                            if (typeof customTokenSeparator === "string") {
                                html += customTokenSeparator
                            } else {
                                error(7998, "Your tokenSeparatorHTML function did not return a string.")
                            }
                        }
                        html += "</span>"
                    }
                }
                html += "</div>"
            }
            return html
        };
        var buildStringOrFunction = function(cssClass, strOrFn, inputValue) {
            var html = '<li class="' + CSS.listItem + " " + cssClass + '">';
            var type = typeof strOrFn;
            if (type === "string") {
                html += strOrFn
            }
            if (type === "function") {
                html += strOrFn(inputValue, getValue())
            }
            html += "</li>";
            return html
        };
        var buildNoResults = function(noResultsHTML, inputValue) {
            return buildStringOrFunction(CSS.noResults, noResultsHTML, inputValue)
        };
        var buildLoading = function(ajaxLoadingHTML, inputValue) {
            return buildStringOrFunction(CSS.ajaxLoading, ajaxLoadingHTML, inputValue)
        };
        var hidePlaceholder = function() {
            placeholderEl.css("display", "none")
        };
        var showPlaceholder = function() {
            placeholderEl.css("display", "")
        };
        var moveTokenHighlightLeft = function() {
            var selectedEl = tokensEl.find("div." + CSS.selectedTokenGroup);
            if (selectedEl.length !== 1) return;
            var prev = selectedEl.prev("div." + CSS.tokenGroup);
            selectedEl.removeClass(CSS.selectedTokenGroup);
            if (prev.length === 1) {
                prev.addClass(CSS.selectedTokenGroup)
            } else {
                tokensEl.find("div." + CSS.tokenGroup).filter(":last").addClass(CSS.selectedTokenGroup)
            }
        };
        var moveTokenHighlightRight = function() {
            var selectedEl = tokensEl.find("div." + CSS.selectedTokenGroup);
            if (selectedEl.length !== 1) return;
            var next = selectedEl.next("div." + CSS.tokenGroup);
            selectedEl.removeClass(CSS.selectedTokenGroup);
            if (next.length === 1) {
                next.addClass(CSS.selectedTokenGroup)
            } else {
                tokensEl.find("div." + CSS.tokenGroup).filter(":first").addClass(CSS.selectedTokenGroup)
            }
        };
        var positionDropdownEl = function() {
            var pos = inputEl.position();
            var height = parseInt(inputEl.height(), 10);
            dropdownEl.css({
                top: height + pos.top,
                left: pos.left
            })
        };
        var highlightFirstOption = function() {
            highlightOption(dropdownEl.find("li." + CSS.option).filter(":first"))
        };
        var clearTokenGroupHighlight = function() {
            tokensEl.find("div." + CSS.tokenGroup).removeClass(CSS.selectedTokenGroup)
        };
        var highlightLastTokenGroup = function() {
            tokensEl.find("div." + CSS.tokenGroup).removeClass(CSS.selectedTokenGroup).filter(":last").addClass(CSS.selectedTokenGroup)
        };
        var updateTokens = function() {
            var tokenHTML = buildTokens(TOKENS);
            tokensEl.html(tokenHTML);
            if (tokenHTML === "" && INPUT_HAS_FOCUS === false) {
                showPlaceholder()
            } else {
                hidePlaceholder()
            }
        };
        var markFirstLastOptions = function() {
            var listEls = dropdownEl.find("li");
            listEls.removeClass(CSS.firstOption + " " + CSS.lastOption);
            listEls.filter(":first").addClass(CSS.firstOption);
            listEls.filter(":last").addClass(CSS.lastOption)
        };
        var calcTextWidth = function(text) {
            inputWidthProxyEl.html(encode(text) + "WW");
            var cssProps = {};
            for (var i = 0,
            len = CSS_TEXT_PROPS.length; i < len; i++) {
                var cssProp = CSS_TEXT_PROPS[i];
                cssProps[cssProp] = inputEl.css(cssProp)
            }
            inputWidthProxyEl.css(cssProps);
            return parseInt(inputWidthProxyEl.width(), 10)
        };
        var updateInputWidth = function() {
            var inputText = inputEl.val();
            inputEl.css("width", calcTextWidth(inputText) + "px")
        };
        var highlightOption = function(optionEl) {
            dropdownEl.find("li." + CSS.option).removeClass(CSS.highlightedOption);
            $(optionEl).addClass(CSS.highlightedOption)
        };
        var adjustDropdownScroll = function() {
            var highlightedEl = dropdownEl.find("li." + CSS.highlightedOption);
            if (highlightedEl.length !== 1) return;
            var liTop = highlightedEl.position().top;
            var scrollTop = dropdownEl.scrollTop();
            if (dropdownEl.find("li." + CSS.option).filter(":first").hasClass(CSS.highlightedOption) === true) {
                dropdownEl.scrollTop( - 1);
                return
            }
            if (liTop < 0) {
                dropdownEl.scrollTop(scrollTop + liTop);
                return
            }
            var liHeight = highlightedEl.height();
            var ddHeight = dropdownEl.height();
            if (liTop + liHeight > ddHeight) {
                dropdownEl.scrollTop(scrollTop + liTop + liHeight - ddHeight + 6)
            }
        };
        var setCurrentList = function(listName) {
            if (cfg.lists[CURRENT_LIST_NAME].hasOwnProperty("onEnd") === true && typeof cfg.lists[CURRENT_LIST_NAME].onEnd === "function") {
                cfg.lists[CURRENT_LIST_NAME].onEnd()
            }
            if (listExists(listName) !== true) {
                listName = cfg.initialList
            }
            CURRENT_LIST_NAME = listName;
            if (cfg.lists[CURRENT_LIST_NAME].hasOwnProperty("onStart") === true && typeof cfg.lists[CURRENT_LIST_NAME].onStart === "function") {
                cfg.lists[CURRENT_LIST_NAME].onStart()
            }
        };
        var removeList = function(listName) {
            if (CURRENT_LIST_NAME === listName) {
                setCurrentList(cfg.initialList)
            }
            delete cfg.lists[listName]
        };
        var destroyWidget = function() {
            containerEl.html("");
            containerEl.unbind()
        };
        var getValue = function() {
            return deepCopy(TOKENS)
        };
        var setValue = function(newValue) {
            var oldValue = getValue();
            if (typeof cfg.onChange === "function") {
                var possibleNewValue = cfg.onChange(newValue, oldValue);
                if (validValue(possibleNewValue) === true) {
                    newValue = possibleNewValue
                } else {
                    error(3776, "Invalid Value returned from your custom onChange function.", possibleNewValue)
                }
            }
            TOKENS = newValue;
            updateTokens();
            positionDropdownEl()
        };
        var listExists = function(listName) {
            return typeof listName === "string" && cfg.lists.hasOwnProperty(listName) === true
        };
        var showOptions = function(html) {
            positionDropdownEl();
            dropdownEl.css("display", "").html(html);
            OPTIONS_SHOWING = true
        };
        var hideOptions = function() {
            dropdownEl.css("display", "none").html("");
            if (TOKENS.length === 0 && INPUT_HAS_FOCUS === false) {
                showPlaceholder()
            }
            OPTIONS_SHOWING = false
        };
        var isTokenGroupHighlighted = function() {
            return tokensEl.find("div." + CSS.selectedTokenGroup).length === 1
        };
        var removeTokenGroup = function(tokenGroupIndex) {
            tokenGroupIndex = parseInt(tokenGroupIndex, 10);
            if (tokenGroupIndex === TOKENS.length - 1) {
                setCurrentList(cfg.initialList);
                ADD_NEXT_TOKEN_TO_NEW_TOKEN_GROUP = true
            }
            var newTokens = deepCopy(TOKENS);
            newTokens.splice(tokenGroupIndex, 1);
            setValue(newTokens);
            if (typeof cfg.maxTokenGroups === "number" && TOKENS.length < cfg.maxTokenGroups) {
                inputEl.css("display", "")
            }
        };
        var removeHighlightedTokenGroup = function() {
            if (isTokenGroupHighlighted() !== true) return;
            var tokenGroupIndex = parseInt(tokensEl.find("div." + CSS.selectedTokenGroup).attr("data-token-group-index"), 10);
            if (validTokenGroupIndex(tokenGroupIndex) !== true) {
                clearTokenGroupHighlight();
                return
            }
            removeTokenGroup(tokenGroupIndex);
            if (INPUT_HAS_FOCUS === true) {
                hideOptions();
                focusInput()
            }
        };
        var createTokenFromOption = function(option) {
            return {
                tokenHTML: option.tokenHTML,
                value: option.value
            }
        };
        var getChildrenListName = function(option, parentList) {
            if (option.children === false) {
                return false
            }
            if (typeof option.children === "string" && listExists(option.children) === true) {
                return option.children
            }
            if (typeof parentList.children === "string" && listExists(parentList.children) === true) {
                return parentList.children
            }
            return false
        };
        var addHighlightedOption = function() {
            var highlightedEl = dropdownEl.find("li." + CSS.highlightedOption);
            if (highlightedEl.length !== 1) return;
            var optionId = highlightedEl.attr("data-option-id");
            if (VISIBLE_OPTIONS.hasOwnProperty(optionId) !== true) {
                error(8292, 'Could not find optionID "' + optionId + '".');
                hideOptions();
                return
            }
            var list = cfg.lists[CURRENT_LIST_NAME];
            var option = VISIBLE_OPTIONS[optionId];
            var token = createTokenFromOption(option);
            var newTokens = deepCopy(TOKENS);
            if (ADD_NEXT_TOKEN_TO_NEW_TOKEN_GROUP === true) {
                newTokens.push([token])
            } else {
                newTokens[newTokens.length - 1].push(token)
            }
            setValue(newTokens);
            var childrenListName = getChildrenListName(option, list);
            if (typeof childrenListName === "string") {
                setCurrentList(childrenListName);
                ADD_NEXT_TOKEN_TO_NEW_TOKEN_GROUP = false
            } else {
                setCurrentList(cfg.initialList);
                ADD_NEXT_TOKEN_TO_NEW_TOKEN_GROUP = true
            }
            hideOptions();
            inputEl.val("");
            if (typeof cfg.maxTokenGroups === "number" && TOKENS.length >= cfg.maxTokenGroups && ADD_NEXT_TOKEN_TO_NEW_TOKEN_GROUP === true) {
                inputEl.css("display", "none")
            } else {
                inputEl.focus()
            }
        };
        var ajaxSuccess = function(data, list, inputValue, preProcess) {
            if (INPUT_HAS_FOCUS !== true || OPTIONS_SHOWING !== true) {
                return
            }
            if (typeof preProcess === "function") {
                data = preProcess(data, inputValue, getValue())
            }
            var options = [];
            if (isArray(data) === true) {
                for (var i = 0; i < data.length; i++) {
                    if (validOptionObject(data[i]) !== true) continue;
                    data[i] = expandOptionObject(data[i], list);
                    data[i].optionHTML = highlightMatchChars(data[i].optionHTML, inputValue);
                    options.push(data[i])
                }
            }
            var html = "";
            if (options.length === 0 && isOptionShowing() === false) {
                html = buildNoResults(list.noResultsHTML, inputValue)
            }
            if (options.length > 0) {
                html = buildOptions(options, list, true)
            }
            dropdownEl.find("li." + CSS.ajaxLoading).replaceWith(html);
            markFirstLastOptions();
            if (isOptionHighlighted() === false) {
                highlightFirstOption()
            }
        };
        var ajaxError = function(errType, list, inputValue) {
            if (INPUT_HAS_FOCUS !== true || OPTIONS_SHOWING !== true) {
                return
            }
            if (errType === "abort") return;
            var errorMsg = '<li class="' + CSS.listItem + " " + CSS.ajaxError + '">';
            if (typeof list.ajaxErrorHTML === "string") {
                errorMsg += list.ajaxErrorHTML
            }
            if (typeof list.ajaxErrorHTML === "function") {
                errorMsg += list.ajaxErrorHTML(errType, inputValue, getValue())
            }
            errorMsg += "</li>";
            dropdownEl.find("li." + CSS.ajaxLoading).replaceWith(errorMsg)
        };
        var sendAjaxRequest = function(list, inputValue) {
            var ajaxOpts = {
                dataType: "json",
                preProcess: false,
                type: "GET"
            };
            var ajaxOpts2 = {};
            if (typeof list.ajaxOpts === "function") {
                ajaxOpts2 = list.ajaxOpts(inputValue, getValue())
            }
            if (isObject(list.ajaxOpts) === true) {
                ajaxOpts2 = $.extend(true, {},
                list.ajaxOpts)
            }
            if (typeof ajaxOpts2.url === "string") {
                ajaxOpts2.url = ajaxOpts2.url.replace(/\{input\}/g, encodeURIComponent(inputValue))
            }
            if (typeof ajaxOpts2.url === "function") {
                ajaxOpts2.url = ajaxOpts2.url(inputValue, getValue())
            }
            var noShotGuy = ["async", "complete", "error", "statusCode", "success"];
            for (var i = 0; i < noShotGuy.length; i++) {
                if (ajaxOpts2.hasOwnProperty(noShotGuy[i]) === true) {
                    error(1273, "You cannot include properties that effect control flow on ajaxOpts: " + '"async", "complete", "error", "statusCode", "success"', noShotGuy[i])
                }
                delete ajaxOpts[noShotGuy[i]]
            }
            $.extend(ajaxOpts, ajaxOpts2);
            if (typeof ajaxOpts.url !== "string") {
                error(8721, "AJAX url must be a string. Did you forget to include one on ajaxOpts?", ajaxOpts.url);
                hideOptions();
                return
            }
            var cacheKey = false;
            if (ajaxOpts.type.toUpperCase() === "GET") {
                cacheKey = "GET " + ajaxOpts.url
            }
            ajaxOpts.error = function(xhr, errType, exceptionObj) {
                ajaxError(errType, list, inputValue)
            };
            ajaxOpts.success = function(data) {
                if (list.cacheAjax === true && cacheKey !== false) {
                    storeInCache(cacheKey, data, list.cacheAjaxSeconds)
                }
                ajaxSuccess(data, list, inputValue, ajaxOpts.preProcess)
            };
            if (list.cacheAjax === true && cacheKey !== false) {
                var data = getFromCache(cacheKey);
                if (data !== false) {
                    ajaxSuccess(data, list, inputValue, ajaxOpts.preProcess);
                    return
                }
            }
            AJAX_BUFFER_TIMEOUT = window.setTimeout(function() {
                AJAX_OBJECT = $.ajax(ajaxOpts)
            },
            AJAX_BUFFER_LENGTH)
        };
        var findHTMLChars = function(str) {
            var chars = (str + "").split("");
            var result = [];
            var inATag = false;
            var inEscapeSequence = false;
            for (var i = 0; i < chars.length; i++) {
                if (chars[i] === "<") {
                    inATag = true;
                    result.push({
                        "char": "<",
                        html: true
                    });
                    continue
                }
                if (inATag === true && chars[i] === ">") {
                    inATag = false;
                    result.push({
                        "char": ">",
                        html: true
                    });
                    continue
                }
                if (chars[i] === "&") {
                    inEscapeSequence = true;
                    result.push({
                        "char": "&",
                        html: true
                    });
                    continue
                }
                if (inEscapeSequence === true && chars[i] === ";") {
                    inEscapeSequence = false;
                    result.push({
                        "char": ";",
                        html: true
                    });
                    continue
                }
                if (inATag === true || inEscapeSequence === true) {
                    result.push({
                        "char": chars[i],
                        html: true
                    });
                    continue
                }
                result.push({
                    "char": chars[i],
                    html: false
                })
            }
            return result
        };
        var removeHTMLChars = function(str) {
            var chars = findHTMLChars(str);
            var str2 = "";
            for (var i = 0; i < chars.length; i++) {
                if (chars[i].html === false) {
                    str2 += chars[i]["char"]
                }
            }
            return str2
        };
        var highlightMatchChars = function(optionHTML, input) {
            var charsToHighlight = {};
            var inputChars = (input + "").split("");
            for (var i = 0; i < inputChars.length; i++) {
                charsToHighlight[inputChars[i].toLowerCase()] = true;
                charsToHighlight[inputChars[i].toUpperCase()] = true
            }
            var optionHTMLArr = findHTMLChars(optionHTML);
            var optionHTML2 = "";
            for (var i = 0; i < optionHTMLArr.length; i++) {
                var c = optionHTMLArr[i]["char"];
                var html = optionHTMLArr[i].html;
                if (html === false && charsToHighlight.hasOwnProperty(c) === true) {
                    optionHTML2 += "<strong>" + c + "</strong>";
                    continue
                }
                optionHTML2 += c
            }
            for (var i = 0; i < HTML.length; i++) {
                if (charsToHighlight.hasOwnProperty(HTML[i]["char"]) !== true) continue;
                optionHTML2 = optionHTML2.replace(HTML[i].htmlRegex, "<strong>" + HTML[i].html + "</strong>")
            }
            return optionHTML2
        };
        var isFrontMatch = function(input, str) {
            return input.toLowerCase() === str.toLowerCase().substring(0, input.length)
        };
        var isSubstringMatch = function(input, str) {
            return str.toLowerCase().indexOf(input.toLowerCase()) !== -1
        };
        var isCharMatch = function(input, str) {
            input = input + "";
            str = str + "";
            if (input === "" || str === "") {
                return false
            }
            var inputChars = input.split(""),
            inputCharsObj = {},
            i;
            for (i = 0; i < inputChars.length; i++) {
                inputCharsObj[inputChars[i].toLowerCase()] = true
            }
            inputChars = keys(inputCharsObj);
            str = str.toLowerCase();
            for (i = 0; i < inputChars.length; i++) {
                if (str.indexOf(inputChars[i]) === -1) {
                    return false
                }
            }
            return true
        };
        var matchOptionsSpecial = function(options, input, list) {
            var i, len = options.length,
            options2 = [];
            for (i = 0; i < len; i++) {
                if (isFrontMatch(input, options[i]._matchValue) === true) {
                    options2.push(options[i]);
                    options[i] = false
                }
            }
            if (list.allowFreeform === true) {
                options2.push(expandOptionObject({
                    optionHTML: encode('"' + input + '"'),
                    tokenHTML: encode(input),
                    value: input
                },
                list))
            }
            for (i = 0; i < len; i++) {
                if (options[i] === false) continue;
                if (isSubstringMatch(input, options[i]._matchValue) === true) {
                    options2.push(options[i]);
                    options[i] = false
                }
            }
            for (i = 0; i < len; i++) {
                if (options[i] === false) continue;
                if (isCharMatch(input, options[i]._matchValue) === true) {
                    options2.push(options[i])
                }
            }
            return options2
        };
        var htmlCharToSentinel = function(str) {
            str = str + "";
            for (var i = 0; i < HTML.length; i++) {
                str = str.replace(HTML[i].htmlRegex, HTML_SENTINELS[i].sentinel)
            }
            return str
        };
        var sentinelToHtmlChar = function(str) {
            str = str + "";
            for (var i = 0; i < HTML.length; i++) {
                str = str.replace(HTML_SENTINELS[i].sentinelRegex, HTML[i].html)
            }
            return str
        };
        var findCharsToMatchAgainst = function(str) {
            str = htmlCharToSentinel(str);
            str = removeHTMLChars(str);
            str = sentinelToHtmlChar(str);
            str = decode(str);
            return str
        };
        var matchOptions = function(input, list) {
            var options = deepCopy(list.options);
            if (input === "") {
                return options
            }
            var options2 = [];
            for (var i = 0; i < options.length; i++) {
                options[i]._matchValue = findCharsToMatchAgainst(options[i].optionHTML)
            }
            options2 = matchOptionsSpecial(options, input, list);
            return options2
        };
        var isOptionShowing = function() {
            return dropdownEl.find("li." + CSS.option).length > 0
        };
        var isOptionHighlighted = function() {
            return dropdownEl.find("li." + CSS.highlightedOption).length !== 0
        };
        var pressUpArrow = function() {
            var highlightedEl = dropdownEl.find("li." + CSS.highlightedOption);
            highlightedEl.removeClass(CSS.highlightedOption);
            var prevEl = highlightedEl.prevAll("li." + CSS.option).first();
            if (prevEl.length === 1) {
                prevEl.addClass(CSS.highlightedOption)
            } else {
                dropdownEl.find("li." + CSS.option).last().addClass(CSS.highlightedOption)
            }
            adjustDropdownScroll()
        };
        var pressDownArrow = function() {
            var highlightedEl = dropdownEl.find("li." + CSS.highlightedOption);
            highlightedEl.removeClass(CSS.highlightedOption);
            var nextEl = highlightedEl.nextAll("li." + CSS.option).first();
            if (nextEl.length === 1) {
                nextEl.addClass(CSS.highlightedOption)
            } else {
                dropdownEl.find("li." + CSS.option).first().addClass(CSS.highlightedOption)
            }
            adjustDropdownScroll()
        };
        var pressEscapeKey = function() {
            hideOptions();
            clearTokenGroupHighlight()
        };
        var pressBackspaceOnEmptyInput = function() {
            if (isTokenGroupHighlighted() === true) {
                removeHighlightedTokenGroup()
            } else {
                highlightLastTokenGroup()
            }
        };
        var pressEnterOrTab = function() {
            addHighlightedOption()
        };
        var pressRegularKey = function() {
            window.clearTimeout(AJAX_BUFFER_TIMEOUT);
            if (AJAX_OBJECT.hasOwnProperty("abort") === true && typeof AJAX_OBJECT.abort === "function") {
                AJAX_OBJECT.abort()
            }
            window.setTimeout(positionDropdownEl, 100);
            window.setTimeout(positionDropdownEl, 200);
            window.setTimeout(positionDropdownEl, 300);
            var inputValue = inputEl.val();
            if (inputValue !== "") {
                clearTokenGroupHighlight()
            }
            var list = cfg.lists[CURRENT_LIST_NAME];
            var options = matchOptions(inputValue, list);
            if (list.hasOwnProperty("matchOptions") === true && typeof list.matchOptions === "function") {
                options = list.matchOptions(inputValue, options, deepCopy(list.options), getValue())
            }
            if (options.length === 0 && inputValue === "" && list.ajaxEnabled === false) {
                hideOptions();
                return
            }
            if (options.length === 0 && list.ajaxEnabled === false) {
                showOptions(buildNoResults(list.noResultsHTML, inputValue));
                return
            }
            if (list.highlightMatches === true) {
                for (var i = 0; i < options.length; i++) {
                    options[i].optionHTML = highlightMatchChars(options[i].optionHTML, inputValue)
                }
            }
            var html = buildOptions(options, list);
            if (list.ajaxEnabled === true) {
                html += buildLoading(list.ajaxLoadingHTML, inputValue)
            }
            showOptions(html);
            markFirstLastOptions();
            highlightFirstOption();
            if (list.ajaxEnabled === true) {
                sendAjaxRequest(list, inputValue)
            }
        };
        var clickPage = function(e) {
            if ($(e.target).parents().index(containerEl) === -1) {
                hideOptions()
            }
        };
        var clickContainerElement = function() {
            if (INPUT_HAS_FOCUS !== true) {
                inputEl.focus()
            }
        };
        var clickTokenGroup = function(e) {
            e.stopPropagation();
            hideOptions();
            clearTokenGroupHighlight();
            $(this).addClass(CSS.selectedTokenGroup)
        };
        var clickRemoveTokenGroup = function(e) {
            e.stopPropagation();
            hideOptions();
            clearTokenGroupHighlight();
            $(this).parents("div." + CSS.tokenGroup).addClass(CSS.selectedTokenGroup);
            removeHighlightedTokenGroup()
        };
        var clickOption = function(e) {
            e.stopPropagation();
            highlightOption(this);
            addHighlightedOption()
        };
        var mouseoverOption = function() {
            highlightOption(this)
        };
        var focusInput = function() {
            if (typeof cfg.maxTokenGroups === "number" && TOKENS.length >= cfg.maxTokenGroups && ADD_NEXT_TOKEN_TO_NEW_TOKEN_GROUP === true) {
                return
            }
            INPUT_HAS_FOCUS = true;
            if (listExists(CURRENT_LIST_NAME) !== true) {
                setCurrentList(cfg.initialList)
            }
            hidePlaceholder();
            clearTokenGroupHighlight();
            positionDropdownEl();
            pressRegularKey();
            adjustDropdownScroll()
        };
        var blurInput = function() {
            INPUT_HAS_FOCUS = false;
            if (TOKENS.length === 0 && OPTIONS_SHOWING === false && inputEl.val() === "") {
                showPlaceholder()
            }
        };
        var keydownInput = function(e) {
            var keyCode = e.which;
            var inputValue = inputEl.val();
            if (keyCode === KEYS.TAB && inputValue === "") {
                hideOptions();
                return
            }
            if (keyCode === KEYS.TAB && OPTIONS_SHOWING === false) {
                return
            }
            if (keyCode === KEYS.ENTER || keyCode === KEYS.NUMPAD_ENTER) {
                e.preventDefault();
                addHighlightedOption();
                return
            }
            if (keyCode === KEYS.TAB && inputValue !== "") {
                e.preventDefault();
                addHighlightedOption();
                return
            }
            if (keyCode === KEYS.BACKSPACE && inputValue === "") {
                e.preventDefault();
                e.stopPropagation();
                pressBackspaceOnEmptyInput();
                return
            }
            if (keyCode === KEYS.LEFT && inputValue === "") {
                highlightLastTokenGroup();
                return
            }
            if (keyCode === KEYS.UP) {
                e.preventDefault();
                pressUpArrow();
                return
            }
            if (keyCode === KEYS.DOWN) {
                e.preventDefault();
                pressDownArrow();
                return
            }
            if (keyCode === KEYS.LEFT || keyCode === KEYS.RIGHT) {
                return
            }
            if (keyCode === KEYS.ESCAPE) {
                pressEscapeKey();
                return
            }
            window.setTimeout(pressRegularKey, 5)
        };
        var keydownWindow = function(e) {
            if (INPUT_HAS_FOCUS === true || OPTIONS_SHOWING === true || isTokenGroupHighlighted() !== true) {
                return
            }
            var keyCode = e.which;
            if (keyCode === KEYS.BACKSPACE || keyCode === KEYS.DELETE) {
                e.preventDefault();
                removeHighlightedTokenGroup();
                return
            }
            if (keyCode === KEYS.ESCAPE) {
                clearTokenGroupHighlight();
                return
            }
            if (keyCode === KEYS.LEFT) {
                moveTokenHighlightLeft();
                return
            }
            if (keyCode === KEYS.RIGHT) {
                moveTokenHighlightRight()
            }
        };
        widget.addOption = function(listName, option) {
            if (validListName(listName) !== true) {
                error(8366, "The first argument to the addOption method must be a non-empty string.");
                return false
            }
            if (listExists(listName) !== true) {
                error(5732, 'Error in addOption method. List "' + listName + '" does not exist.');
                return false
            }
            if (validOptionObject(option) !== true) {
                error(7887, "Invalid option passed to addOption method.", option);
                return false
            }
            option = expandOptionObject(option, cfg.lists[listName]);
            cfg.lists[listName].options.push(option);
            return true
        };
        widget.blur = function() {
            inputEl.blur();
            hideOptions()
        };
        widget.clear = function() {
            setValue([])
        };
        widget.destroy = function() {
            destroyWidget()
        };
        widget.focus = function(callback) {
            window.setTimeout(function() {
                inputEl.focus();
                if (typeof callback === "function") {
                    callback()
                }
            },
            5)
        };
        widget.getList = function(name) {
            if (validListName(name) !== true) {
                error(2789, "The first argument to the getList method must be a non-empty string.");
                return false
            }
            if (listExists(name) !== true) {
                return false
            }
            return cfg.lists[name]
        };
        widget.getLists = function() {
            return cfg.lists
        };
        widget.getValue = function() {
            return getValue()
        };
        widget.list = function(name, list) {
            if (arguments.length === 1) {
                return widget.getList(name)
            }
            if (arguments.length === 2) {
                return widget.setList(name, list)
            }
            error(5938, "Wrong number of arguments passed to list method.");
            return false
        };
        widget.pressDown = function() {
            if (OPTIONS_SHOWING !== true) return;
            pressDownArrow()
        };
        widget.pressEnter = function() {
            if (OPTIONS_SHOWING !== true) return;
            pressEnterOrTab()
        };
        widget.pressUp = function() {
            if (OPTIONS_SHOWING !== true) return;
            pressUpArrow()
        };
        widget.removeList = function(name) {
            if (validListName(name) !== true) {
                error(2231, "The first argument to the removeList method " + "must be a non-empty string.");
                return false
            }
            if (listExists(name) !== true) {
                error(1328, 'Error in removeList method. List "' + name + '" does not exist.');
                return false
            }
            if (name === cfg.initialList) {
                error(1424, "Error in removeList method. You cannot remove the initialList " + '"' + name + '"');
                return false
            }
            removeList(name);
            return true
        };
        widget.removeTokenGroup = function(tokenGroupIndex) {
            if (validTokenGroupIndex(tokenGroupIndex) !== true) {
                error(4823, "Error in removeTokenGroup method. " + 'Token group index "' + tokenGroupIndex + '" does not exist.');
                return false
            }
            removeTokenGroup(tokenGroupIndex);
            return getValue()
        };
        widget.setInput = function(input) {
            if (typeof input !== "string") {
                error(4922, "The first argument to the setInput method must be a string.");
                return false
            }
            inputEl.focus();
            inputEl.val(input);
            pressRegularKey();
            return true
        };
        widget.setList = function(name, list) {
            if (validListName(name) !== true) {
                error(7283, "The first argument to the setList method must be a non-empty string.");
                return false
            }
            if (validListObject(list) !== true) {
                error(2732, "The list object passed to the setList method is not valid.", list);
                return false
            }
            cfg.lists[name] = expandListObject(list);
            return true
        };
        widget.setValue = function(value) {
            if (validValue(value) !== true) {
                error(6823, "Invalid value passed to the setValue method.", value);
                return false
            }
            setValue(expandValue(value));
            return true
        };
        widget.val = function(value) {
            if (arguments.length === 0) {
                return widget.getValue()
            }
            if (arguments.length === 1) {
                return widget.setValue(value)
            }
            error(9992, "Wrong number of arguments passed to val method.");
            return false
        };
        var addEvents = function() {
            containerEl.bind("click", clickContainerElement);
            containerEl.delegate("input." + CSS.input, "keydown", keydownInput);
            containerEl.delegate("input." + CSS.input, "change keyup", updateInputWidth);
            containerEl.delegate("input." + CSS.input, "focus", focusInput);
            containerEl.delegate("input." + CSS.input, "blur", blurInput);
            containerEl.delegate("li." + CSS.option, "click", clickOption);
            containerEl.delegate("li." + CSS.option, "mouseover", mouseoverOption);
            containerEl.delegate("div." + CSS.tokenGroup, "click", clickTokenGroup);
            containerEl.delegate("span." + CSS.removeTokenGroup, "click", clickRemoveTokenGroup);
            $("html").bind("click touchstart", clickPage);
            $(window).bind("keydown", keydownWindow)
        };
        var initDom = function() {
            containerEl.html(buildWidget());
            inputEl = containerEl.find("input." + CSS.input);
            dropdownEl = containerEl.find("ul." + CSS.dropdown);
            placeholderEl = containerEl.find("div." + CSS.placeholder);
            tokensEl = containerEl.find("div." + CSS.tokensContainer);
            inputWidthProxyEl = containerEl.find("span." + CSS.inputWidthProxy);
            placeholderEl.html(cfg.placeholderHTML)
        };
        var init = function() {
            if (sanityChecks() !== true) return;
            initDom();
            addEvents();
            updateTokens()
        };
        init();
        return widget
    };
    window.AutoComplete.htmlEncode = encode
})();
var rpApp = angular.module("rpApp", ["ngAnimate"]);
rpApp.config(["$httpProvider",
function($httpProvider) {
    $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"
}]);
function RPCtrl($scope, $http) {
    var readThreads = {};
    var replyDiv = {};
    $scope.showMessage = {};
    $scope.notify = false;
    $scope.notificationMsg = "";
    $scope.loggedIn = angular.element("body").hasClass("logged-in");
    $scope.homeTabs = {
        popularCategories: true
    };
    $scope.messageTabs = {
        inbox: true
    };
    $scope.toggleMessage = function(threadId, messageType) {
        if (!$scope.showMessage[threadId]) {
            $scope.showMessage[threadId] = true;
            $scope.markThread(threadId, messageType, "read")
        } else {
            $scope.showMessage[threadId] = false
        }
    };
    $scope.markThread = function(threadId, type, value) {
        $http({
            method: "GET",
            url: Routing.generate("account_message_mark_thread_" + value, {
                thread: threadId,
                type: type
            })
        }).success(function(data, status, headers, config) {
            if (value == "read" || value == "unread") {
                $scope.setAllRead(threadId, value)
            } else if (value == "deleted" || value == "undeleted") {
                $scope.hideThread(threadId);
                if (value == "deleted") {
                    $scope.notificationMsg = "The message was deleted successfully!"
                } else if (value == "undeleted") {
                    $scope.notificationMsg = "The message was restored successfully!"
                }
                $scope.notify = true
            }
        }).error(function(data, status, headers, config) {
            console.log("Error marking thread " + threadId + " " + value + ":");
            console.log(data)
        })
    };
    $scope.replyThread = function(threadId, submit, event) {
        if (event) {
            event.preventDefault()
        }
        if (submit) {
            var form = $("#form-" + threadId.toLowerCase().replace(/\W+/, "-"));
            var formData = form.serialize();
            $http({
                method: "POST",
                url: Routing.generate("account_message_reply", {
                    thread: threadId
                }),
                data: formData,
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded"
                }
            }).success(function(data, status, headers, config) {
                form.html(data["html"])
            }).error(function(data, status, headers, config) {
                form.html('<p class="red"><i class="fa fa-exclamation-circle"></i>Error sending reply. We apologize for the inconvenience.</p>');
                console.log("Error replying to thread " + threadId + ".");
                console.log(data)
            })
        } else {
            replyDiv[threadId] = true;
            return false
        }
    };
    $scope.cancelReply = function(threadId) {
        replyDiv[threadId] = false
    };
    $scope.replyDiv = function(threadId) {
        return replyDiv[threadId]
    };
    $scope.setAllRead = function(threadId, allRead) {
        readThreads[threadId] = allRead
    };
    $scope.allRead = function(threadId, tf) {
        if (tf) {
            return readThreads[threadId] == "read"
        } else {
            return readThreads[threadId]
        }
    };
    var hiddenThreads = [];
    $scope.hideThread = function(threadId) {
        hiddenThreads.push(threadId)
    };
    $scope.threadIsHidden = function(threadId) {
        return hiddenThreads.indexOf(threadId) !== -1
    };
    $scope.initEqualHeights = function() {
        setTimeout(function() {
            $.initEqualHeights()
        },
        10)
    };
    $scope.dismissNotify = function() {
        $scope.notify = false
    }
}
RPCtrl.$inject = ["$scope", "$http"];
function reloadWithParams(params) {
    var url = $.url().attr("path");
    var count = 0;
    for (param in params) {
        count++
    }
    if (count > 0) {
        url = url + "?" + $.param(params)
    }
    window.location.replace(url)
}
function setPerPage() {
    var url = $.url();
    var perPage = $("#items-per-page").val();
    var params = $.extend({},
    $.url().param(), {
        perpage: perPage
    });
    reloadWithParams(params)
}
function setSortOrder() {
    var url = $.url();
    var sortOrder = $("#sort-order").val();
    var params = $.url().param();
    if (sortOrder) {
        params = $.extend(params, {
            "sort-order": sortOrder
        })
    } else {
        delete params["sort-order"]
    }
    reloadWithParams(params)
}
function searchTheseResults() {
    var params = $.url().param();
    var searchTerms = $('input[name="q"]', "#search-these-results").val();
    var searchScope = $('input[name="qscope"]:checked', "#search-these-results").val();
    if (searchScope == "narrow") {
        if (searchTerms) {
            params = $.extend(params, {
                q: searchTerms,
                scope: searchScope
            })
        } else {
            delete params["q"];
            delete params["scope"]
        }
        reloadWithParams(params)
    } else {
        params = {
            q: searchTerms,
            scope: searchScope
        };
        window.location.replace(Routing.generate("browse", params))
    }
}
function setPriceRange() {
    var pricemin = $('input[name="pricemin"]').val();
    var pricemax = $('input[name="pricemax"]').val();
    var params = $.url().param();
    if (pricemin) {
        params = $.extend(params, {
            pricemin: pricemin
        })
    } else {
        delete params["pricemin"]
    }
    if (pricemax) {
        params = $.extend(params, {
            pricemax: pricemax
        })
    } else {
        delete params["pricemax"]
    }
    reloadWithParams(params)
}
function setYearRange() {
    var yearmin = $('input[name="yearmin"]').val();
    var yearmax = $('input[name="yearmax"]').val();
    var params = $.url().param();
    if (yearmin) {
        params = $.extend(params, {
            yearmin: yearmin
        })
    } else {
        delete params["yearmin"]
    }
    if (yearmax) {
        params = $.extend(params, {
            yearmax: yearmax
        })
    } else {
        delete params["yearmax"]
    }
    reloadWithParams(params)
}
function setLocation() {
    var params = $.url().param();
    var location = $('#set-location > input[name="location"]').val();
    params = $.extend(params, {
        location: location
    });
    reloadWithParams(params)
}
function initListingsFlexsliders() {
    $("#listing-images-carousel").flexslider({
        animation: "slide",
        controlNav: false,
        animationLoop: false,
        slideshow: false,
        itemWidth: 80,
        itemMargin: 5,
        asNavFor: "#listing-images",
        prevText: "",
        nextText: ""
    });
    $("#listing-images").flexslider({
        animation: "slide",
        controlNav: false,
        animationLoop: false,
        slideshow: false,
        sync: "#listing-images-carousel",
        prevText: "",
        nextText: ""
    })
}
function initListingsDropzones(files, images) {
    Dropzone.autoDiscover = false;
    var sortableOptions = {
        handles: "img",
        placeholder: '<div class="dz-preview dz-image-preview sortable-placeholder"></div>'
    };
    var filesDropzone = new Dropzone("#files-form", {
        paramName: "form[file]",
        addRemoveLinks: true,
        previewsContainer: "#dropzone-files"
    });
    files.forEach(function(file, i, files) {
        filesDropzone.emit("addedfile", file)
    });
    filesDropzone.on("success",
    function(file, response) {
        file.filename = response.filename;
        file.path = response.path;
        file.deleteform = $(response.deleteform);
        files.push(file)
    });
    filesDropzone.on("removedfile",
    function(file) {
        var response = $.post(file.deleteform.attr("action"), file.deleteform.serializeArray())
    });
    var imagesDropzone = new Dropzone("#images-form", {
        paramName: "form[file]",
        addRemoveLinks: true,
        previewsContainer: "#dropzone-images"
    });
    imagesDropzone.on("addedfile",
    function(image) {
        if (image.id) {
            $(image.previewElement).attr("data-id", image.id)
        }
    });
    images.forEach(function(image, i, images) {
        imagesDropzone.emit("addedfile", image);
        imagesDropzone.emit("thumbnail", image, image.thumbpath)
    });
    if (images.length > 0) {
        $("#images-form .dz-message").hide()
    }
    imagesDropzone.on("success",
    function(image, response) {
        image.filename = response.filename;
        image.path = response.path;
        image.deleteform = $(response.deleteform);
        images.push(image)
    });
    imagesDropzone.on("removedfile",
    function(file) {
        var response = $.post(file.deleteform.attr("action"), file.deleteform.serializeArray())
    });
    $("#dropzone-images").sortable(sortableOptions).bind("sortupdate", sortupdate)
}
function sortupdate(event, data) {
    console.log("Positioning #" + data.item.data("id") + " into position " + data.item.index());
    $.get(Routing.generate("account_listings_reorder_file", {
        id: data.item.data("id"),
        position: data.item.index()
    }))
}
$(document).ready(function() {
    $("#items-per-page").change(setPerPage);
    $("#sort-order").change(setSortOrder);
    $(".confirm").on("click",
    function(event) {
        if (! (message = $(this).attr("data-confirm-message"))) message = "Are you sure you want to perform this action?";
        if (confirm(message)) {
            return
        } else {
            event.stopPropagation();
            return false
        }
    })
});
$(window).load(function() {
    $(".card.listing .equal").equalHeights();
    function Toggler(element) {
        var primaryClass = "fa-caret-right";
        var alternateClass = "fa-caret-down";
        if (element.hasClass(primaryClass)) {
            element.removeClass(primaryClass);
            element.addClass(alternateClass)
        } else if (element.hasClass(alternateClass)) {
            element.removeClass(alternateClass);
            element.addClass(primaryClass)
        }
    }
    var categoriesDropdown = $("li.categories").has("ul");
    var expanders = $(".expander");
    categoriesDropdown.css("color", "#0A82AE");
    categoriesDropdown.children("a").css("color", "#0A82AE");
    expanders.each(function() {
        $(this).on("click",
        function(e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            var targeter = $(this).attr("data-target");
            categoryChildren = $("li#" + targeter).children("ul");
            if (categoryChildren.length > 0) {
                Toggler($(this));
                categoryChildren.toggle()
            }
        })
    })
});